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

pull/1150/head
zhangdaiscott 2020-05-03 12:43:53 +08:00
parent 046831e700
commit 9e046a07d4
335 changed files with 12894 additions and 27387 deletions

View File

@ -7,12 +7,12 @@
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)
[![](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 forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot)

View File

@ -1,7 +1,7 @@
Ant Design Jeecg Vue
====
当前最新版本: 2.1.4发布日期2020-02-24
当前最新版本: 2.2.0发布日期2020-05-06
Overview
----

View File

@ -6,19 +6,19 @@ function resolve (dir) {
}
module.exports = {
context: path.resolve(__dirname, './'),
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'config': resolve('config'),
'@': resolve('src'),
'@views': resolve('src/views'),
'@comp': resolve('src/components'),
'@core': resolve('src/core'),
'@utils': resolve('src/utils'),
'@entry': resolve('src/entry'),
'@router': resolve('src/router'),
'@store': resolve('src/store')
}
}
}
context: path.resolve(__dirname, './'),
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'config': resolve('config'),
'@': resolve('src'),
'@views': resolve('src/views'),
'@comp': resolve('src/components'),
'@core': resolve('src/core'),
'@utils': resolve('src/utils'),
'@entry': resolve('src/entry'),
'@router': resolve('src/router'),
'@store': resolve('src/store')
}
},
}

View File

@ -1,19 +1,19 @@
{
"name": "vue-antd-jeecg",
"version": "2.1.4",
"version": "2.2.0",
"private": true,
"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",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@antv/data-set": "^0.10.2",
"@jeecg/antd-online-214": "^2.1.41",
"@antv/data-set": "^0.11.2",
"@jeecg/antd-online-beta220": "^1.0.1",
"@tinymce/tinymce-vue": "^2.0.0",
"ant-design-vue": "^1.4.11",
"apexcharts": "^3.6.5",
"ant-design-vue": "^1.5.2",
"area-data": "^5.0.6",
"axios": "^0.18.0",
"clipboard": "^2.0.4",
"codemirror": "^5.46.0",
@ -25,22 +25,20 @@
"md5": "^2.2.1",
"nprogress": "^0.2.0",
"tinymce": "^5.1.4",
"tui-editor": "^1.4.10",
"viser-vue": "^2.4.4",
"vue": "^2.6.10",
"vue-apexcharts": "^1.3.2",
"vue-class-component": "^6.0.0",
"vue-area-linkage": "^5.1.0",
"vue-cropper": "^0.4.8",
"vue-i18n": "^8.7.0",
"vue-loader": "^15.7.0",
"vue-ls": "^3.2.0",
"vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.9",
"vue-property-decorator": "^7.3.0",
"vue-router": "^3.0.1",
"vue-splitpane": "^1.0.4",
"vuedraggable": "^2.20.0",
"vuex": "^3.0.1",
"vuex-class": "^0.3.1"
"vuex": "^3.1.0"
},
"devDependencies": {
"@babel/polyfill": "^7.2.5",
@ -49,9 +47,10 @@
"@vue/cli-service": "^3.3.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"compression-webpack-plugin": "^3.1.0",
"eslint": "^5.16.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-loader": "^4.1.0",
"vue-template-compiler": "^2.6.10"
@ -91,7 +90,7 @@
"vue/no-use-v-if-with-v-for": 0,
"vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0,
"no-console": 0,
"no-console": 0,
"no-tabs": 0,
"indent": [1, 4]
}

View File

@ -7679,3 +7679,23 @@ font.medium {
font.weak {
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 三级联动样式 --------------

View File

@ -0,0 +1,30 @@
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);
})
}

View File

@ -1,16 +1,11 @@
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 editRole = (params)=>putAction("/sys/role/edit",params);
// const getRoleList = (params)=>getAction("/sys/role/list",params);
// const deleteRole = (params)=>deleteAction("/sys/role/delete",params);
// const deleteRoleList = (params)=>deleteAction("/sys/role/deleteBatch",params);
const checkRoleCode = (params)=>getAction("/sys/role/checkRoleCode",params);
const queryall = (params)=>getAction("/sys/role/queryall",params);
@ -19,8 +14,6 @@ const addUser = (params)=>postAction("/sys/user/add",params);
const editUser = (params)=>putAction("/sys/user/edit",params);
const queryUserRole = (params)=>getAction("/sys/user/queryUserRole",params);
const getUserList = (params)=>getAction("/sys/user/list",params);
// const deleteUser = (params)=>deleteAction("/sys/user/delete",params);
// const deleteUserList = (params)=>deleteAction("/sys/user/deleteBatch",params);
const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
//验证用户是否存在
const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params);
@ -31,20 +24,15 @@ const changePassword = (params)=>putAction("/sys/user/changePassword",params);
const addPermission= (params)=>postAction("/sys/permission/add",params);
const editPermission= (params)=>putAction("/sys/permission/edit",params);
const getPermissionList = (params)=>getAction("/sys/permission/list",params);
/*update_begin author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params);
const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params);
const getSystemSubmenuBatch = (params) => getAction('/sys/permission/getSystemSubmenuBatch', params)
/*update_end author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
// const deletePermission = (params)=>deleteAction("/sys/permission/delete",params);
// const deletePermissionList = (params)=>deleteAction("/sys/permission/deleteBatch",params);
const queryTreeList = (params)=>getAction("/sys/permission/queryTreeList",params);
const queryTreeListForRole = (params)=>getAction("/sys/role/queryTreeList",params);
const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params);
const queryRolePermission = (params)=>getAction("/sys/permission/queryRolePermission",params);
const saveRolePermission = (params)=>postAction("/sys/permission/saveRolePermission",params);
//const queryPermissionsByUser = (params)=>getAction("/sys/permission/queryByUser",params);
const queryPermissionsByUser = (params)=>getAction("/sys/permission/getUserPermissionByToken",params);
const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params);
const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params);
@ -66,24 +54,26 @@ const saveDeptRolePermission = (params)=>postAction("/sys/sysDepartPermission/sa
const queryMyDepartTreeList = (params)=>getAction("/sys/sysDepart/queryMyDeptTreeList",params);
//日志管理
//const getLogList = (params)=>getAction("/sys/log/list",params);
const deleteLog = (params)=>deleteAction("/sys/log/delete",params);
const deleteLogList = (params)=>deleteAction("/sys/log/deleteBatch",params);
//数据字典
const addDict = (params)=>postAction("/sys/dict/add",params);
const editDict = (params)=>putAction("/sys/dict/edit",params);
//const getDictList = (params)=>getAction("/sys/dict/list",params);
const treeList = (params)=>getAction("/sys/dict/treeList",params);
// const delDict = (params)=>deleteAction("/sys/dict/delete",params);
//const getDictItemList = (params)=>getAction("/sys/dictItem/list",params);
const addDictItem = (params)=>postAction("/sys/dictItem/add",params);
const editDictItem = (params)=>putAction("/sys/dictItem/edit",params);
//const delDictItem = (params)=>deleteAction("/sys/dictItem/delete",params);
//const delDictItemList = (params)=>deleteAction("/sys/dictItem/deleteBatch",params);
//字典标签专用通过code获取字典数组
export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItems/${code}`,params);
//从缓存中获取字典配置
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);
@ -91,23 +81,18 @@ const doReovkeData = (params)=>getAction("/sys/annountCement/doReovkeData",param
//获取系统访问量
const getLoginfo = (params)=>getAction("/sys/loginfo",params);
const getVisitInfo = (params)=>getAction("/sys/visitInfo",params);
//数据日志访问
// const getDataLogList = (params)=>getAction("/sys/dataLog/list",params);
// 根据部门主键查询用户信息
const queryUserByDepId = (params)=>getAction("/sys/user/queryUserByDepId",params);
// 查询用户角色表里的所有信息
const queryUserRoleMap = (params)=>getAction("/sys/user/queryUserRoleMap",params);
// 重复校验
const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params);
// 加载分类字典
const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params);
const checkRuleByCode = (params) => getAction('/sys/checkRule/checkByCode', params)
//我的通告
const getUserNoticeInfo= (params)=>getAction("/sys/sysAnnouncementSend/getMyAnnouncementSend",params);
export {
// imgView,
// doMian,
addRole,
editRole,
checkRoleCode,
@ -147,7 +132,6 @@ export {
getLoginfo,
getVisitInfo,
queryUserByDepId,
queryUserRoleMap,
duplicateCheck,
queryTreeListForRole,
getSystemMenuList,
@ -160,7 +144,9 @@ export {
queryTreeListForDeptRole,
queryDeptRolePermission,
saveDeptRolePermission,
queryMyDepartTreeList
queryMyDepartTreeList,
getUserNoticeInfo,
getDictItemsFromCache
}

View File

@ -55,4 +55,19 @@ export function logout(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'
}
})
}

View File

@ -1,3 +1,4 @@
import Vue from 'vue'
import { axios } from '@/utils/request'
const api = {
@ -113,16 +114,64 @@ export function downFile(url,parameter){
}
/**
* 访
* @param avatar
* @param imgerver
* @param str
*
* @param url
* @param fileName
* @param parameter
* @returns {*}
*/
export function getFileAccessHttpUrl(avatar,imgerver,subStr) {
if(avatar && avatar.indexOf(subStr) != -1 ){
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 subStr
* @returns {*}
*/
export function getFileAccessHttpUrl(avatar,subStr) {
if(!subStr) subStr = 'http'
if(avatar && avatar.startsWith(subStr)){
return avatar;
}else{
return imgerver + "/" + avatar;
if(avatar && avatar.length>0 && avatar.indexOf('[')==-1){
return window._CONFIG['staticDomainURL'] + "/" + avatar;
}
}
}

View File

@ -0,0 +1,259 @@
.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;
}

View File

@ -0,0 +1,15 @@
/** [表格主题样式一] 表格强制列不换行 */
.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;
}
}

View File

@ -1,11 +1,18 @@
/*列表上方操作按钮区域*/
.ant-card-body .table-operator {
margin-bottom: 18px;
margin-bottom: 8px;
}
/** Button按钮间距 */
.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设置 可以控制列表大小*/
.ant-table-tbody .ant-table-row td {
@ -45,3 +52,7 @@
/*erp风格子表外框padding设置*/
.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;
}

View File

@ -8,14 +8,14 @@ const init = (callback) => {
console.log("-------单点登录开始-------");
let token = Vue.ls.get(ACCESS_TOKEN);
let st = getUrlParam("ticket");
var sevice = "http://"+window.location.host+"/";
let sevice = "http://"+window.location.host+"/";
if(token){
loginSuccess(callback);
}else{
if(st){
validateSt(st,sevice,callback);
}else{
var serviceUrl = encodeURIComponent(sevice);
let serviceUrl = encodeURIComponent(sevice);
window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl;
}
}
@ -26,14 +26,14 @@ const SSO = {
};
function getUrlParam(paraName) {
var url = document.location.toString();
var arrObj = url.split("?");
let url = document.location.toString();
let arrObj = url.split("?");
if (arrObj.length > 1) {
var arrPara = arrObj[1].split("&");
var arr;
let arrPara = arrObj[1].split("&");
let arr;
for (var i = 0; i < arrPara.length; i++) {
for (let i = 0; i < arrPara.length; i++) {
arr = arrPara[i].split("=");
if (arr != null && arr[0] == paraName) {
@ -57,8 +57,8 @@ function validateSt(ticket,service,callback){
if(res.success){
loginSuccess(callback);
}else{
var sevice = "http://"+window.location.host+"/";
var serviceUrl = encodeURIComponent(sevice);
let sevice = "http://"+window.location.host+"/";
let serviceUrl = encodeURIComponent(sevice);
window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl;
}
}).catch((err) => {

View File

@ -1,31 +1,20 @@
<script>
import Tooltip from 'ant-design-vue/es/tooltip'
import { cutStrByFullLength, getStrFullLength } from '@/components/_util/StringUtil'
/*
const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
const TooltipOverlayStyle = {
overflowWrap: 'break-word',
wordWrap: 'break-word',
};
*/
export default {
name: 'Ellipsis',
components: {
Tooltip
},
props: {
prefixCls: {
type: String,
default: 'ant-pro-ellipsis'
},
tooltip: {
type: Boolean
type: Boolean,
default: true,
},
length: {
type: Number,
required: true
default: 25,
},
lines: {
type: Number,
@ -36,28 +25,25 @@
default: false
}
},
methods: {
getStrDom (str) {
return (
<span>{ cutStrByFullLength(str, this.length) + '...' }</span>
)
},
getTooltip ( fullStr) {
return (
<Tooltip>
<template slot="title">{ fullStr }</template>
{ this.getStrDom(fullStr) }
</Tooltip>
)
}
},
render () {
methods: {},
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
)
let text = ''
// 处理没有default插槽时的特殊情况
if (this.$slots.default) {
text = this.$slots.default.map(vNode => vNode.text).join('')
}
// 判断是否显示 tooltip
if (tooltip && getStrFullLength(text) > length) {
return (
<a-tooltip>
<template slot="title">{text}</template>
<span>{cutStrByFullLength(text, this.length) + '…'}</span>
</a-tooltip>
)
} else {
return (<span>{text}</span>)
}
}
}
</script>

View File

@ -0,0 +1,79 @@
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)
}
}
}
}

View File

@ -0,0 +1,54 @@
<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>

View File

@ -3,6 +3,10 @@
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
</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-option :value="undefined"></a-select-option>
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
@ -14,7 +18,7 @@
</template>
<script>
import {ajaxGetDictItems} from '@/api/api'
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
export default {
name: "JDictSelectTag",
@ -52,11 +56,17 @@
},
computed: {
getValueSting(){
return this.value ? this.value.toString() : null;
return this.value != null ? this.value.toString() : null;
},
},
methods: {
initDictData() {
//优先从缓存中读取字典配置
if(getDictItemsFromCache(this.dictCode)){
this.dictOptions = getDictItemsFromCache(this.dictCode);
return
}
//根据字典Code, 初始化字典数组
ajaxGetDictItems(this.dictCode, null).then((res) => {
if (res.success) {

View File

@ -4,7 +4,7 @@
* date: 20190109
*/
import {ajaxGetDictItems} from '@/api/api'
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
import {getAction} from '@/api/manage'
/**
@ -16,6 +16,13 @@ export async function initDictOptions(dictCode) {
if (!dictCode) {
return 'Code!';
}
//优先从缓存中读取字典配置
if(getDictItemsFromCache(dictCode)){
let res = {}
res.result = getDictItemsFromCache(dictCode);
res.success = true;
return res;
}
//获取字典数组
let res = await ajaxGetDictItems(dictCode);
return res;
@ -28,16 +35,25 @@ export async function initDictOptions(dictCode) {
* @return String
*/
export function filterDictText(dictOptions, text) {
//--update-begin----author:sunjianlei---date:20191025------for:修复字典替换方法在字典没有加载完成之前报错的问题、修复没有找到字典时返回空值的问题---
if (dictOptions instanceof Array) {
for (let dictItem of dictOptions) {
if (text === dictItem.value) {
return dictItem.text
// --update-begin----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
if (text != null && dictOptions instanceof Array) {
let result = []
// 允许多个逗号分隔
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
//--update-end----author:sunjianlei---date:20191025------for:修复字典替换方法在字典没有加载完成之前报错的问题、修复没有找到字典时返回空值的问题---
// --update-end----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
}
/**
@ -49,24 +65,28 @@ export function filterDictText(dictOptions, text) {
export function filterMultiDictText(dictOptions, text) {
//js “!text” 认为0为空所以做提前处理
if(text === 0 || text === '0'){
for (let dictItem of dictOptions) {
if (text == dictItem.value) {
return dictItem.text
if(dictOptions){
for (let dictItem of dictOptions) {
if (text == dictItem.value) {
return dictItem.text
}
}
}
}
if(!text || !dictOptions || dictOptions.length==0){
if(!text || text=='null' || !dictOptions || dictOptions.length==0){
return ""
}
let re = "";
text = text.toString()
let arr = text.split(",")
dictOptions.forEach(function (option) {
for(let i=0;i<arr.length;i++){
if (arr[i] === option.value) {
re += option.text+",";
break;
if(option){
for(let i=0;i<arr.length;i++){
if (arr[i] === option.value) {
re += option.text+",";
break;
}
}
}
});
@ -81,20 +101,42 @@ export function filterMultiDictText(dictOptions, text) {
* @param children
* @returns string
*/
export async function ajaxFilterDictText(dictCode, key) {
export function filterDictTextByCache(dictCode, key) {
if(key==null ||key.length==0){
return;
}
if (!dictCode) {
return 'Code!';
}
//console.log(`key : ${key}`);
if (!key) {
return '';
}
//通过请求读取字典文本
let res = await getAction(`/sys/dict/getDictText/${dictCode}/${key}`);
if (res.success) {
// console.log('restult: '+ res.result);
return res.result;
} else {
return '';
//优先从缓存中读取字典配置
if(getDictItemsFromCache(dictCode)){
let item = getDictItemsFromCache(dictCode).filter(t => t["value"] == key)
if(item && item.length>0){
return item[0]["text"]
}
}
}
/** 通过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([])
})
}

View File

@ -10,6 +10,7 @@
:disabled="disabled"
mode="multiple"
:placeholder="placeholder"
:getPopupContainer="(node) => node.parentNode"
allowClear>
<a-select-option
v-for="(item,index) in dictOptions"
@ -24,7 +25,7 @@
</template>
<script>
import {ajaxGetDictItems} from '@/api/api'
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
export default {
name: 'JMultiSelectTag',
props: {
@ -49,12 +50,18 @@
this.tagType = this.type
}
//获取字典数据
this.initDictData();
//this.initDictData();
},
watch:{
options: function(val){
this.setCurrentDictOptions(val);
},
dictCode:{
immediate:true,
handler() {
this.initDictData()
},
},
value (val) {
if(!val){
this.arrayValue = []
@ -68,6 +75,11 @@
if(this.options && this.options.length>0){
this.dictOptions = [...this.options]
}else{
//优先从缓存中读取字典配置
if(getDictItemsFromCache(this.dictCode)){
this.dictOptions = getDictItemsFromCache(this.dictCode);
return
}
//根据字典Code, 初始化字典数组
ajaxGetDictItems(this.dictCode, null).then((res) => {
if (res.success) {

View File

@ -4,6 +4,8 @@
v-if="async"
showSearch
labelInValue
:disabled="disabled"
:getPopupContainer="(node) => node.parentNode"
@search="loadData"
:placeholder="placeholder"
v-model="selectedAsyncValue"
@ -19,7 +21,9 @@
<a-select
v-else
:getPopupContainer="(node) => node.parentNode"
showSearch
:disabled="disabled"
:placeholder="placeholder"
optionFilterProp="children"
style="width: 100%"
@ -35,7 +39,7 @@
</template>
<script>
import { ajaxGetDictItems } from '@/api/api'
import { ajaxGetDictItems,getDictItemsFromCache } from '@/api/api'
import debounce from 'lodash/debounce';
import { getAction } from '../../api/manage'
@ -43,7 +47,7 @@
name: 'JSearchSelectTag',
props:{
disabled: Boolean,
value: String,
value: [String, Number],
dict: String,
dictOptions: Array,
async: Boolean,
@ -71,8 +75,12 @@
immediate:true,
handler(val){
if(!val){
this.selectedValue=[]
this.selectedAsyncValue=[]
if(val==0){
this.initSelectValue()
}else{
this.selectedValue=[]
this.selectedAsyncValue=[]
}
}else{
this.initSelectValue()
}
@ -100,7 +108,7 @@
})
}
}else{
this.selectedValue = this.value
this.selectedValue = this.value.toString()
}
},
loadData(value){
@ -132,11 +140,28 @@
this.options = [...this.dictOptions]
}else{
//根据字典Code, 初始化字典数组
ajaxGetDictItems(this.dict, null).then((res) => {
if (res.success) {
this.options = res.result;
}
})
let dictStr = ''
if(this.dict){
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;
}
})
}
}
}
},

View File

@ -0,0 +1,156 @@
<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(`JAreaLinkagetype${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>

View File

@ -96,7 +96,7 @@
loadRoot(){
let param = {
pid:this.pid,
pcode:this.pcode,
pcode:!this.pcode?'0':this.pcode,
condition:this.condition
}
getAction(this.url,param).then(res=>{
@ -122,8 +122,6 @@
this.treeValue = []
}else{
getAction(this.view,{ids:this.value}).then(res=>{
console.log(124345)
console.log(124345,res)
if(res.success){
let values = this.value.split(',')
this.treeValue = res.result.map((item, index) => ({

View File

@ -1,6 +1,6 @@
<template>
<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">
<textarea ref="textarea"></textarea>
@ -91,6 +91,7 @@
return {
// 内部真实的内容
code: '',
iconType: 'fullscreen',
hasCode:false,
// 默认的语法类型
mode: 'javascript',
@ -155,6 +156,15 @@
}
},
watch: {
fullCoder:{
handler(value) {
if(value){
this.iconType="fullscreen-exit"
}else{
this.iconType="fullscreen"
}
}
},
// value: {
// immediate: false,
// handler(value) {
@ -408,6 +418,7 @@
.full-screen-child {
min-height: 120px;
max-height: 320px;
overflow:hidden;
}
}

View File

@ -51,7 +51,7 @@
},
getCalendarContainer: {
type: Function,
default: () => document.body
default: (node) => node.parentNode
}
},
data () {

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/textcolor'
import 'tinymce/plugins/fullscreen'
import { uploadAction,getFileAccessHttpUrl } from '@/api/manage'
export default {
components: {
Editor
@ -65,8 +66,21 @@
menubar: false,
toolbar_drawer: false,
images_upload_handler: (blobInfo, success) => {
const img = 'data:image/jpeg;base64,' + blobInfo.base64()
success(img)
let formData = new FormData()
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

View File

@ -1,6 +1,6 @@
<template>
<div :class="disabled?'jeecg-form-container-disabled':''">
<fieldset disabled>
<fieldset :disabled="disabled">
<slot name="detail"></slot>
</fieldset>
<slot name="edit"></slot>
@ -46,4 +46,16 @@
-ms-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>

View File

@ -1,203 +0,0 @@
<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>

View File

@ -44,7 +44,6 @@
data(){
return {
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
urlView:window._CONFIG['staticDomainURL'],
uploadLoading:false,
picUrl:false,
headers:{},
@ -103,7 +102,7 @@
let fileList = [];
let arr = paths.split(",")
for(var a=0;a<arr.length;a++){
let url = getFileAccessHttpUrl(arr[a],this.urlView,"http");
let url = getFileAccessHttpUrl(arr[a]);
fileList.push({
uid: uidGenerator(),
name: getFileName(arr[a]),
@ -156,7 +155,7 @@
getAvatarView(){
if(this.fileList.length>0){
let url = this.fileList[0].url
return getFileAccessHttpUrl(url,this.urlView,"http")
return getFileAccessHttpUrl(url)
}
},
handlePathChange(){

View File

@ -32,7 +32,12 @@
handler:function(){
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: {
prop: 'value',

View File

@ -0,0 +1,30 @@
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'
]
}

View File

@ -0,0 +1,121 @@
<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>

View File

@ -1,8 +1,8 @@
<template>
<a-modal
ref="modal"
class="j-modal-box"
:class="{'fullscreen':innerFullscreen,'no-title':isNoTitle,'no-footer':isNoFooter,}"
:class="getClass(modalClass)"
:style="getStyle(modalStyle)"
:visible="visible"
v-bind="_attrs"
v-on="$listeners"
@ -38,6 +38,8 @@
<script>
import { getClass, getStyle } from '@/utils/props-util'
export default {
name: 'JModal',
props: {
@ -47,13 +49,18 @@
// 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符
fullscreen: {
type: Boolean,
default: true
default: false
},
// 是否允许切换全屏(允许后右上角会出现一个按钮)
switchFullscreen: {
type: Boolean,
default: false
},
// 点击确定按钮的时候是否关闭弹窗
okClose: {
type: Boolean,
default: true
},
},
data() {
return {
@ -73,6 +80,22 @@
}
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() {
return !this.title && !this.allSlotsKeys.includes('title')
},
@ -90,7 +113,7 @@
},
// 切换全屏的按钮图标
fullscreenButtonIcon() {
return this.innerFullscreen ? 'fullscreen' : 'fullscreen-exit'
return this.innerFullscreen ? 'fullscreen-exit' : 'fullscreen'
},
},
watch: {
@ -105,12 +128,21 @@
},
methods: {
getClass(clazz) {
return { ...getClass(this), ...clazz }
},
getStyle(style) {
return { ...getStyle(this), ...style }
},
close() {
this.$emit('update:visible', false)
},
handleOk() {
this.close()
if (this.okClose) {
this.close()
}
},
handleCancel() {
this.close()
@ -167,6 +199,7 @@
.right {
width: 56px;
position: inherit;
.ant-modal-close {
right: 56px;
@ -180,5 +213,13 @@
}
}
}
@media (max-width: 767px) {
.j-modal-box.fullscreen {
margin: 0;
max-width: 100vw;
}
}
</style>

View File

@ -1,31 +1,37 @@
<template>
<div class="j-super-query-box">
<div @click="visible=true">
<slot>
<a-tooltip v-if="superQueryFlag" :mouseLeaveDelay="0.2">
<template slot="title">
<span></span>
<a-divider type="vertical"/>
<a @click="handleReset"></a>
</template>
<a-button type="primary">
<a-icon type="appstore" theme="twoTone" :spin="true"></a-icon>
<slot name="button" :isActive="superQueryFlag" :isMobile="izMobile" :open="handleOpen" :reset="handleReset">
<a-tooltip v-if="superQueryFlag" v-bind="tooltipProps" :mouseLeaveDelay="0.2">
<!-- begin -->
<span v-show="false">{{tooltipProps}}</span>
<!-- end -->
<template slot="title">
<span></span>
<a-divider type="vertical"/>
<a @click="handleReset"></a>
</template>
<a-button-group>
<a-button type="primary" @click="handleOpen">
<a-icon type="appstore" theme="twoTone" spin/>
<span></span>
</a-button>
</a-tooltip>
<a-button v-else type="primary" icon="filter" @click="visible=true"></a-button>
</slot>
</div>
<a-button v-if="izMobile" type="primary" icon="delete" @click="handleReset"/>
</a-button-group>
</a-tooltip>
<a-button v-else type="primary" icon="filter" @click="handleOpen"></a-button>
</slot>
<a-modal
<j-modal
title="高级查询构造器"
:width="1000"
:visible="visible"
@cancel="handleCancel"
:mask="false"
:fullscreen="izMobile"
class="j-super-query-modal"
style="top:5%;max-height: 95%;">
style="top:5%;max-height: 95%;"
>
<template slot="footer">
<div style="float: left">
@ -40,7 +46,7 @@
<a-row>
<a-col :sm="24" :md="24-5">
<a-empty v-if="queryParamsModel.length === 0">
<a-empty v-if="queryParamsModel.length === 0" style="margin-bottom: 12px;">
<div slot="description">
<span></span>
<a-divider type="vertical"/>
@ -50,16 +56,20 @@
<a-form v-else layout="inline">
<a-form-item label="过滤条件匹配" style="margin-bottom: 12px;">
<a-select v-model="selectValue" :getPopupContainer="node=>node.parentNode">
<a-select-option value="and">AND</a-select-option>
<a-select-option value="or">OR</a-select-option>
</a-select>
</a-form-item>
<a-row style="margin-bottom: 12px;">
<a-col :md="12" :xs="24">
<a-form-item label="过滤条件匹配" :labelCol="{md: 6,xs:24}" :wrapperCol="{md: 18,xs:24}" style="width: 100%;">
<a-select v-model="matchType" :getPopupContainer="node=>node.parentNode" style="width: 100%;">
<a-select-option value="and">AND</a-select-option>
<a-select-option value="or">OR</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in queryParamsModel" :key="index">
<a-col :span="8">
<a-col :md="8" :xs="24" style="margin-bottom: 12px;">
<a-tree-select
showSearch
v-model="item.field"
@ -75,22 +85,22 @@
</a-tree-select>
</a-col>
<a-col :span="4">
<a-select placeholder="匹配规则" v-model="item.rule" :getPopupContainer="node=>node.parentNode">
<a-col :md="4" :xs="24" style="margin-bottom: 12px;">
<a-select placeholder="匹配规则" :value="item.rule" :getPopupContainer="node=>node.parentNode" @change="handleRuleChange(item,$event)">
<a-select-option value="eq"></a-select-option>
<a-select-option value="like"></a-select-option>
<a-select-option value="right_like">..</a-select-option>
<a-select-option value="left_like">..</a-select-option>
<a-select-option value="in">...</a-select-option>
<a-select-option value="ne"></a-select-option>
<a-select-option value="gt"></a-select-option>
<a-select-option value="ge"></a-select-option>
<a-select-option value="lt"></a-select-option>
<a-select-option value="le"></a-select-option>
<a-select-option value="right_like">..</a-select-option>
<a-select-option value="left_like">..</a-select-option>
<a-select-option value="like"></a-select-option>
<a-select-option value="in">...</a-select-option>
</a-select>
</a-col>
<a-col :span="8">
<a-col :md="8" :xs="24" style="margin-bottom: 12px;">
<template v-if="item.dictCode">
<template v-if="item.type === 'table-dict'">
<j-popup
@ -101,10 +111,14 @@
:destFields="item.dictCode"
></j-popup>
</template>
<j-dict-select-tag v-else v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
<template v-else>
<j-multi-select-tag v-show="allowMultiple(item)" v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
<j-dict-select-tag v-show="!allowMultiple(item)" v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
</template>
</template>
<j-popup v-else-if="item.type === 'popup'" :value="item.val" v-bind="item.popup" group-id="superQuery" @input="(e,v)=>handleChangeJPopup(item,e,v)"/>
<j-select-multi-user
v-else-if="item.type === 'select-user'"
v-else-if="item.type === 'select-user' || item.type === 'sel_user'"
v-model="item.val"
:buttons="false"
:multiple="false"
@ -112,20 +126,34 @@
:returnKeys="['id', item.customReturnField || 'username']"
/>
<j-select-depart
v-else-if="item.type === 'select-depart'"
v-else-if="item.type === 'select-depart' || item.type === 'sel_depart'"
v-model="item.val"
:multi="false"
placeholder="请选择部门"
:customReturnField="item.customReturnField || 'id'"
/>
<a-select v-else-if="item.options instanceof Array" v-model="item.val" :options="item.options" allowClear placeholder="请选择"/>
<a-select
v-else-if="item.options instanceof Array"
v-model="item.val"
:options="item.options"
allowClear
placeholder="请选择"
:mode="allowMultiple(item)?'multiple':''"
/>
<j-area-linkage v-model="item.val" v-else-if="item.type==='area-linkage' || item.type==='pca'" style="width: 100%"/>
<j-date v-else-if=" item.type=='date' " v-model="item.val" placeholder="请选择日期" style="width: 100%"></j-date>
<j-date v-else-if=" item.type=='datetime' " v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"></j-date>
<a-time-picker v-else-if="item.type==='time'" :value="item.val ? moment(item.val,'HH:mm:ss') : null" format="HH:mm:ss" style="width: 100%" @change="(time,value)=>item.val=value"/>
<a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
<a-input v-else v-model="item.val" placeholder="请输入值"/>
</a-col>
<a-col :span="4">
<a-col :md="4" :xs="0" style="margin-bottom: 12px;">
<a-button @click="handleAdd" icon="plus"></a-button>&nbsp;
<a-button @click="handleDel( index )" icon="minus"></a-button>
</a-col>
<a-col :md="0" :xs="24" style="margin-bottom: 12px;text-align: right;">
<a-button @click="handleAdd" icon="plus"></a-button>&nbsp;
<a-button @click="handleDel( index )" icon="minus"></a-button>
</a-col>
@ -142,14 +170,14 @@
</div>
<a-empty v-if="treeData.length === 0" class="j-super-query-history-empty" description="没有保存任何查询"/>
<a-empty v-if="saveTreeData.length === 0" class="j-super-query-history-empty" description="没有保存任何查询"/>
<a-tree
v-else
class="j-super-query-history-tree"
showIcon
:treeData="treeData"
:treeData="saveTreeData"
:selectedKeys="[]"
@select="handleTreeSelect"
@rightClick="handleTreeRightClick"
>
</a-tree>
</a-card>
@ -165,19 +193,24 @@
<a-input v-model="prompt.value"></a-input>
</a-modal>
</a-modal>
</j-modal>
</div>
</template>
<script>
import moment from 'moment'
import * as utils from '@/utils/util'
import { mixinDevice } from '@/utils/mixin'
import JDate from '@/components/jeecg/JDate.vue'
import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
import JMultiSelectTag from '@/components/dict/JMultiSelectTag'
import JAreaLinkage from '@comp/jeecg/JAreaLinkage'
export default {
name: 'JSuperQuery',
components: { JDate, JSelectDepart, JSelectMultiUser },
mixins: [mixinDevice],
components: { JAreaLinkage, JMultiSelectTag, JDate, JSelectDepart, JSelectMultiUser },
props: {
/*
fieldList: [{
@ -208,14 +241,16 @@
},
// 保存查询条件的唯一 code通过该 code 区分
// 默认为 null代表以当前路由全路径为区分Code
saveCode: {
type: String,
default: 'testSaveCode'
default: null
}
},
data() {
return {
moment,
fieldTreeData: [],
prompt: {
@ -224,26 +259,40 @@
},
visible: false,
queryParamsModel: [{}],
queryParamsModel: [],
treeIcon: <a-icon type="file-text"/>,
treeData: [],
// 保存查询条件的treeData
saveTreeData: [],
// 保存查询条件的前缀名
saveCodeBefore: 'JSuperQuerySaved_',
selectValue: 'and',
superQueryFlag: false
// 查询类型过滤条件匹配and、or
matchType: 'and',
superQueryFlag: false,
}
},
computed: {
izMobile() {
return this.device === 'mobile'
},
tooltipProps() {
return this.izMobile ? { visible: false } : {}
},
fullSaveCode() {
let saveCode = this.saveCode
if (saveCode == null || saveCode === '') {
saveCode = this.$route.fullPath
}
return this.saveCodeBefore + saveCode
},
},
watch: {
// 当 saveCode 变化时,重新查询已保存的条件
saveCode: {
fullSaveCode: {
immediate: true,
handler(val) {
let list = this.$ls.get(this.saveCodeBefore + val)
handler() {
let list = this.$ls.get(this.fullSaveCode)
if (list instanceof Array) {
this.treeData = list.map(item => {
item.icon = this.treeIcon
return item
})
this.saveTreeData = list.map(i => this.renderSaveTreeData(i))
}
}
},
@ -280,25 +329,35 @@
methods: {
show() {
if (!this.queryParamsModel || this.queryParamsModel.length == 0) {
this.queryParamsModel = [{}]
if (!this.queryParamsModel || this.queryParamsModel.length === 0) {
this.resetLine()
}
this.visible = true
},
handleOk() {
if (!this.isNullArray(this.queryParamsModel)) {
let event = {
matchType: this.selectValue,
params: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
matchType: this.matchType,
params: this.removeEmptyObject(this.queryParamsModel)
}
console.log('------>', event)
this.emitCallback(event.params, event.matchType)
// 移动端模式下关闭弹窗
if (this.izMobile) {
this.visible = false
}
this.emitCallback(event)
} else {
this.emitCallback()
this.$message.warn("不能查询空条件")
}
},
emitCallback(params, matchType) {
this.superQueryFlag = !!params
emitCallback(event = {}) {
let { params = [], matchType = this.matchType } = event
this.superQueryFlag = (params && params.length > 0)
for (let param of params) {
if (Array.isArray(param.val)) {
param.val = param.val.join(',')
}
}
console.debug('------>', { params, matchType })
this.$emit(this.callback, params, matchType)
},
handleCancel() {
@ -309,27 +368,40 @@
this.visible = false
},
handleAdd() {
this.queryParamsModel.push({})
this.addNewLine()
},
addNewLine() {
this.queryParamsModel.push({ rule: 'eq' })
},
resetLine() {
this.superQueryFlag = false
this.queryParamsModel = []
this.addNewLine()
},
handleDel(index) {
this.queryParamsModel.splice(index, 1)
},
handleSelected(node, item) {
let { type, options, dictCode, dictTable, customReturnField } = node.dataRef
let { type, options, dictCode, dictTable, customReturnField, popup } = node.dataRef
item['type'] = type
item['options'] = options
item['dictCode'] = dictCode
item['dictTable'] = dictTable
item['customReturnField'] = customReturnField
if (popup) {
item['popup'] = popup
}
this.$set(item, 'val', undefined)
},
handleOpen() {
this.show()
},
handleReset() {
this.superQueryFlag = false
this.queryParamsModel = [{}]
this.resetLine()
this.emitCallback()
},
handleSave() {
let queryParams = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
let queryParams = this.removeEmptyObject(this.queryParamsModel)
if (this.isNullArray(queryParams)) {
this.$message.warning('')
} else {
@ -338,56 +410,65 @@
}
},
handlePromptOk() {
let { value } = this.prompt
// 判断有没有重名
let filterList = this.treeData.filter(i => i.title === value)
if(!value){
this.$message.warning('')
return
}
// 取出查询条件
let records = this.removeEmptyObject(this.queryParamsModel)
// 判断有没有重名的
let filterList = this.saveTreeData.filter(i => i.originTitle === value)
if (filterList.length > 0) {
this.$confirm({
content: `${value} `,
onOk: () => {
this.prompt.visible = false
filterList[0].records = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
filterList[0].records = records
this.saveToLocalStore()
this.$message.success('')
}
})
} else {
// 没有重名的,直接添加
this.prompt.visible = false
this.treeData.push({
// 添加到树列表中
this.saveTreeData.push(this.renderSaveTreeData({
title: value,
icon: this.treeIcon,
records: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
})
matchType: this.matchType,
records: records
}))
// 保存到 LocalStore
this.saveToLocalStore()
this.$message.success('')
}
},
handleTreeSelect(idx, event) {
if (event.selectedNodes[0]) {
this.queryParamsModel = utils.cloneObject(event.selectedNodes[0].data.props.records)
let { matchType, records } = event.selectedNodes[0].data.props
// 将保存的matchType取出兼容旧数据如果没有保存就还是使用原来的
this.matchType = matchType || this.matchType
this.queryParamsModel = utils.cloneObject(records)
}
},
handleTreeRightClick(args) {
handleRemoveSaveTreeItem(event, vNode) {
// 阻止事件冒泡
event.stopPropagation()
this.$confirm({
content: '',
onOk: () => {
let { node: { eventKey } } = args
this.treeData.splice(Number.parseInt(eventKey.substring(2)), 1)
let { eventKey } = vNode
this.saveTreeData.splice(Number.parseInt(eventKey.substring(2)), 1)
this.saveToLocalStore()
this.$message.success('')
},
})
},
// 将查询保存到 LocalStore 里
saveToLocalStore() {
this.$ls.set(this.saveCodeBefore + this.saveCode, this.treeData.map(item => {
return { title: item.title, records: item.records }
}))
let saveValue = this.saveTreeData.map(({ originTitle, matchType, records }) => ({ title: originTitle, matchType, records }))
this.$ls.set(this.fullSaveCode, saveValue)
},
isNullArray(array) {
@ -404,18 +485,70 @@
return false
},
// 去掉数组中的空对象
removeEmptyObject(array) {
removeEmptyObject(arr) {
let array = utils.cloneObject(arr)
for (let i = 0; i < array.length; i++) {
let item = array[i]
if (item == null || Object.keys(item).length <= 0) {
array.splice(i--, 1)
} else {
// 去掉特殊属性
delete item.options
if (Array.isArray(item.options)) {
// 如果有字典属性,就不需要保存 options 了
if (item.dictCode) {
// 去掉特殊属性
delete item.options
}
}
}
}
return array
}
},
/** 渲染保存查询条件的 title加个删除按钮 */
renderSaveTreeData(item) {
item.icon = this.treeIcon
item.originTitle = item['title']
item.title = (fn, vNode) => {
let { originTitle } = vNode.dataRef
return (
<div class="j-history-tree-title">
<span>{originTitle}</span>
<div class="j-history-tree-title-closer" onClick={e => this.handleRemoveSaveTreeItem(e, vNode)}>
<a-icon type="close-circle"/>
</div>
</div>
)
}
return item
},
/** 判断是否允许多选 */
allowMultiple(item) {
return item.rule === 'in'
},
handleRuleChange(item, newValue) {
let oldValue = item.rule
this.$set(item, 'rule', newValue)
// 上一个规则是否是 in且type是字典或下拉
if (oldValue === 'in') {
if (item.dictCode || item.options instanceof Array) {
let value = item.val
if (typeof item.val === 'string') {
value = item.val.split(',')[0]
} else if (Array.isArray(item.val)) {
value = item.val[0]
}
this.$set(item, 'val', value)
}
}
},
handleChangeJPopup(item, e, values) {
item.val = values[item.popup['destFields']]
},
}
}
</script>
@ -428,42 +561,76 @@
.j-super-query-modal {
.j-super-query-history-card /deep/ {
.ant-card-body,
.ant-card-head-title {
.j-super-query-history-card {
/deep/ .ant-card-body,
/deep/ .ant-card-head-title {
padding: 0;
}
.ant-card-head {
/deep/ .ant-card-head {
padding: 4px 8px;
min-height: initial;
}
}
.j-super-query-history-empty /deep/ {
.ant-empty-image {
.j-super-query-history-empty {
/deep/ .ant-empty-image {
height: 80px;
line-height: 80px;
margin-bottom: 0;
}
img {
/deep/ img {
width: 80px;
height: 65px;
}
.ant-empty-description {
/deep/ .ant-empty-description {
color: #afafaf;
margin: 8px 0;
}
}
.j-super-query-history-tree /deep/ {
.ant-tree-switcher {
.j-super-query-history-tree {
.j-history-tree-title {
width: calc(100% - 24px);
position: relative;
display: inline-block;
&-closer {
color: #999999;
position: absolute;
top: 0;
right: 0;
width: 24px;
height: 24px;
text-align: center;
opacity: 0;
transition: opacity 0.3s, color 0.3s;
&:hover {
color: #666666;
}
&:active {
color: #333333;
}
}
&:hover {
.j-history-tree-title-closer {
opacity: 1;
}
}
}
/deep/ .ant-tree-switcher {
display: none;
}
.ant-tree-node-content-wrapper {
/deep/ .ant-tree-node-content-wrapper {
width: 100%;
}
}

View File

@ -0,0 +1,57 @@
<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>

View File

@ -180,7 +180,11 @@
},
onChange(value){
console.log(value)
this.$emit('change', value.value);
if(!value){
this.$emit('change', '');
}else{
this.$emit('change', value.value);
}
this.treeValue = value
},
onSearch(value){

View File

@ -2,6 +2,7 @@
<a-tree-select
allowClear
labelInValue
:getPopupContainer="(node) => node.parentNode"
style="width: 100%"
:disabled="disabled"
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"

View File

@ -1,19 +1,43 @@
<template>
<a-upload
name="file"
:multiple="true"
:action="uploadAction"
:headers="headers"
:data="{'biz':bizPath}"
:fileList="fileList"
:beforeUpload="beforeUpload"
@change="handleChange"
:disabled="disabled"
:returnUrl="returnUrl">
<a-button>
<a-icon type="upload" />{{ text }}
</a-button>
</a-upload>
<div :id="containerId" style="position: relative">
<!-- ---------------------------- begin ------------------------------------- -->
<div class="movety-container" :style="{top:top+'px',left:left+'px',display:moveDisplay}" style="padding:0 8px;position: absolute;z-index: 91;height: 32px;width: 104px;text-align: center;">
<div :id="containerId+'-mover'" :class="showMoverTask?'uploadty-mover-mask':'movety-opt'" style="margin-top: 12px">
<a @click="moveLast" style="margin: 0 5px;"><a-icon type="arrow-left" style="color: #fff;font-size: 16px"/></a>
<a @click="moveNext" style="margin: 0 5px;"><a-icon type="arrow-right" style="color: #fff;font-size: 16px"/></a>
</div>
</div>
<!-- ---------------------------- end ------------------------------------- -->
<a-upload
name="file"
:multiple="true"
:action="uploadAction"
:headers="headers"
:data="{'biz':bizPath}"
:fileList="fileList"
:beforeUpload="beforeUpload"
@change="handleChange"
:disabled="disabled"
:returnUrl="returnUrl"
:listType="complistType"
@preview="handlePreview"
:class="{'uploadty-disabled':disabled}">
<template>
<div v-if="isImageComp">
<a-icon type="plus" />
<div class="ant-upload-text">{{ text }}</div>
</div>
<a-button v-else-if="buttonVisible">
<a-icon type="upload" />{{ text }}
</a-button>
</template>
</a-upload>
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
<img alt="example" style="width: 100%" :src="previewImage" />
</a-modal>
</div>
</template>
<script>
@ -40,10 +64,21 @@
data(){
return {
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
urlDownload:window._CONFIG['staticDomainURL'],
headers:{},
fileList: [],
newFileList: [],
uploadGoOn:true,
previewVisible: false,
//---------------------------- begin 图片左右换位置 -------------------------------------
previewImage: '',
containerId:'',
top:'',
left:'',
moveDisplay:'none',
showMoverTask:false,
moverHold:false,
currentImg:''
//---------------------------- end 图片左右换位置 -------------------------------------
}
},
props:{
@ -90,23 +125,48 @@
required:false,
default: true
},
number:{
type:Number,
required:false,
default: 0
},
buttonVisible:{
type:Boolean,
required:false,
default: true
},
},
watch:{
value(val){
if (val instanceof Array) {
if(this.returnUrl){
this.initFileList(val.join(','))
}else{
this.initFileListArr(val);
value:{
immediate: true,
handler() {
let val = this.value
if (val instanceof Array) {
if(this.returnUrl){
this.initFileList(val.join(','))
}else{
this.initFileListArr(val);
}
} else {
this.initFileList(val)
}
} else {
this.initFileList(val)
}
}
},
computed:{
isImageComp(){
return this.fileType === FILE_TYPE_IMG
},
complistType(){
return this.fileType === FILE_TYPE_IMG?'picture-card':'text'
}
},
created(){
const token = Vue.ls.get(ACCESS_TOKEN);
this.headers = {"X-Access-Token":token}
//---------------------------- begin 图片左右换位置 -------------------------------------
this.headers = {"X-Access-Token":token};
this.containerId = 'container-ty-'+new Date().getTime();
//---------------------------- end 图片左右换位置 -------------------------------------
},
methods:{
@ -117,11 +177,12 @@
}
let fileList = [];
for(var a=0;a<val.length;a++){
let url = getFileAccessHttpUrl(val[a].filePath);
fileList.push({
uid:uidGenerator(),
name:val[a].fileName,
status: 'done',
url: val[a].filePath,
url: url,
response:{
status:"history",
message:val[a].filePath
@ -141,7 +202,7 @@
let fileList = [];
let arr = paths.split(",")
for(var a=0;a<arr.length;a++){
let url = getFileAccessHttpUrl(arr[a],this.urlDownload,"http");
let url = getFileAccessHttpUrl(arr[a]);
fileList.push({
uid:uidGenerator(),
name:getFileName(arr[a]),
@ -172,15 +233,12 @@
this.$emit('change', path);
},
beforeUpload(file){
this.uploadGoOn=true
var fileType = file.type;
if(fileType===FILE_TYPE_IMG){
if(this.fileType===FILE_TYPE_IMG){
if(fileType.indexOf('image')<0){
this.$message.warning('');
return false;
}
}else if(fileType===FILE_TYPE_TXT){
if(fileType.indexOf('image')>=0){
this.$message.warning('');
this.uploadGoOn=false
return false;
}
}
@ -189,13 +247,19 @@
},
handleChange(info) {
console.log("--文件列表改变--")
if(!info.file.status && this.uploadGoOn === false){
info.fileList.pop();
}
let fileList = info.fileList
if(info.file.status==='done'){
if(this.number>0){
fileList = fileList.slice(-this.number);
}
if(info.file.response.success){
fileList = fileList.map((file) => {
if (file.response) {
let reUrl = file.response.message;
file.url = getFileAccessHttpUrl(reUrl,this.urlDownload,"http");
file.url = getFileAccessHttpUrl(reUrl);
}
return file;
});
@ -213,20 +277,16 @@
this.handlePathChange()
}else{
//returnUrl为false时返回文件名称、文件路径及文件大小
fileList = fileList.filter((file) => {
if (file.response) {
return file.response.success === true;
}
return false;
}).map((file) => {
this.newFileList = [];
for(var a=0;a<fileList.length;a++){
var fileJson = {
fileName:file.name,
filePath:file.response.message,
fileSize:file.size
fileName:fileList[a].name,
filePath:fileList[a].response.message,
fileSize:fileList[a].size
};
this.newFileList.push(fileJson);
this.$emit('change', this.newFileList);
});
}
this.$emit('change', this.newFileList);
}
}
},
@ -234,6 +294,115 @@
//如有需要新增 删除逻辑
console.log(file)
},
handlePreview(file){
if(this.fileType === FILE_TYPE_IMG){
this.previewImage = file.url || file.thumbUrl;
this.previewVisible = true;
}else{
location.href=file.url
}
},
handleCancel(){
this.previewVisible = false;
},
//---------------------------- begin 图片左右换位置 -------------------------------------
moveLast(){
//console.log(ev)
//console.log(this.fileList)
//console.log(this.currentImg)
let index = this.getIndexByUrl();
if(index==0){
this.$message.warn('')
}else{
let curr = this.fileList[index].url;
let last = this.fileList[index-1].url;
let arr =[]
for(let i=0;i<this.fileList.length;i++){
if(i==index-1){
arr.push(curr)
}else if(i==index){
arr.push(last)
}else{
arr.push(this.fileList[i].url)
}
}
this.currentImg = last
this.$emit('change',arr.join(','))
}
},
moveNext(){
let index = this.getIndexByUrl();
if(index==this.fileList.length-1){
this.$message.warn('~')
}else{
let curr = this.fileList[index].url;
let next = this.fileList[index+1].url;
let arr =[]
for(let i=0;i<this.fileList.length;i++){
if(i==index+1){
arr.push(curr)
}else if(i==index){
arr.push(next)
}else{
arr.push(this.fileList[i].url)
}
}
this.currentImg = next
this.$emit('change',arr.join(','))
}
},
getIndexByUrl(){
for(let i=0;i<this.fileList.length;i++){
if(this.fileList[i].url === this.currentImg || encodeURI(this.fileList[i].url) === this.currentImg){
return i;
}
}
return -1;
}
},
mounted(){
const moverObj = document.getElementById(this.containerId+'-mover');
moverObj.addEventListener('mouseover',()=>{
this.moverHold = true
this.moveDisplay = 'block';
});
moverObj.addEventListener('mouseout',()=>{
this.moverHold = false
this.moveDisplay = 'none';
});
let picList = document.getElementById(this.containerId)?document.getElementById(this.containerId).getElementsByClassName('ant-upload-list-picture-card'):[];
if(picList && picList.length>0){
picList[0].addEventListener('mouseover',(ev)=>{
ev = ev || window.event;
let target = ev.target || ev.srcElement;
if('ant-upload-list-item-info' == target.className){
this.showMoverTask=false
let item = target.parentElement
this.left = item.offsetLeft
this.top=item.offsetTop+item.offsetHeight-50;
this.moveDisplay = 'block';
this.currentImg = target.getElementsByTagName('img')[0].src
}
});
picList[0].addEventListener('mouseout',(ev)=>{
ev = ev || window.event;
let target = ev.target || ev.srcElement;
//console.log('移除',target)
if('ant-upload-list-item-info' == target.className){
this.showMoverTask=true
setTimeout(()=>{
if(this.moverHold === false)
this.moveDisplay = 'none';
},100)
}
if('ant-upload-list-item ant-upload-list-item-done' == target.className || 'ant-upload-list ant-upload-list-picture-card'== target.className){
this.moveDisplay = 'none';
}
})
//---------------------------- end 图片左右换位置 -------------------------------------
}
},
model: {
prop: 'value',
@ -242,6 +411,24 @@
}
</script>
<style scoped>
<style lang="less">
.uploadty-disabled{
.ant-upload-list-item {
.anticon-close{
display: none;
}
.anticon-delete{
display: none;
}
}
}
//---------------------------- begin 图片左右换位置 -------------------------------------
.uploadty-mover-mask{
background-color: rgba(0, 0, 0, 0.5);
opacity: .8;
color: #fff;
height: 28px;
line-height: 28px;
}
//---------------------------- end 图片左右换位置 -------------------------------------
</style>

View File

@ -0,0 +1,113 @@
<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>

View File

@ -0,0 +1,98 @@
<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>

View File

@ -63,12 +63,14 @@
<script>
import { getAction } from '@/api/manage'
import Ellipsis from '@/components/Ellipsis'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import { cloneObject, pushIfNotExist } from '@/utils/util'
export default {
name: 'JSelectBizComponentModal',
mixins: [JeecgListMixin],
components: { Ellipsis },
props: {
value: {
type: Array,
@ -128,12 +130,15 @@
type: String,
default: 'id'
},
// 过长裁剪长度,设置为 -1 代表不裁剪
ellipsisLength: {
type: Number,
default: 12
},
},
data() {
return {
innerValue: [],
// 表头
innerColumns: this.columns,
// 已选择列表
selectedTable: {
pagination: false,
@ -147,6 +152,7 @@
],
dataSource: [],
},
renderEllipsis: (value) => (<ellipsis length={this.ellipsisLength}>{value}</ellipsis>),
url: { list: this.listUrl },
/* 分页参数 */
ipagination: {
@ -164,6 +170,19 @@
dataSourceMap: {},
}
},
computed: {
// 表头
innerColumns() {
let columns = cloneObject(this.columns)
columns.forEach(column => {
// 给所有的列加上过长裁剪
if (this.ellipsisLength !== -1) {
column.customRender = (text) => this.renderEllipsis(text)
}
})
return columns
},
},
watch: {
value: {
deep: true,

View File

@ -29,7 +29,7 @@ export default {
| selectButtonText | String | | "选择" | 选择按钮的文字 |
| queryParamText | String | | null | 查询条件显示文字,不传则使用 `name` |
| columns | Array | 是 | | 列配置项与antd的table的配置完全一致。列的第一项会被配置成右侧已选择的列表上 |
| columns[0].widthRight | Array | | null | 仅列的第一项可以应用此配置,表示右侧已选择列表的宽度,建议 `70%`,不传则应用`width` |
| columns[0].widthRight | String | | null | 仅列的第一项可以应用此配置,表示右侧已选择列表的宽度,建议 `70%`,不传则应用`width` |
| placeholder | String | | "请选择" | 占位符 |
| disabled | Boolean | | false | 是否禁用 |
| multiple | Boolean | | false | 是否可多选 |

View File

@ -9,8 +9,9 @@
:options="selectOptions"
allowClear
:disabled="disabled"
:open="false"
:open="selectOpen"
style="width: 100%;"
@dropdownVisibleChange="handleDropdownVisibleChange"
@click.native="visible=(buttons?visible:true)"
/>
</slot>
@ -85,7 +86,8 @@
selectValue: [],
selectOptions: [],
dataSourceMap: {},
visible: false
visible: false,
selectOpen: false,
}
},
computed: {
@ -128,6 +130,13 @@
this.selectOptions = options
this.dataSourceMap = dataSourceMap
},
handleDropdownVisibleChange() {
// 解决antdv自己的bug —— open 设置为 false 了,点击后还是添加了 open 样式,导致点击事件失效
this.selectOpen = true
this.$nextTick(() => {
this.selectOpen = false
})
},
}
}
</script>
@ -142,7 +151,7 @@
}
.right {
width: @width ;
width: @width;
}
.full {
@ -150,7 +159,7 @@
}
/deep/ .ant-select-search__field {
display: none !important;
}
display: none !important;
}
}
</style>

View File

@ -2,6 +2,7 @@
<!-- -->
<j-select-biz-component
:value="value"
:ellipsisLength="25"
:listUrl="url.list"
:columns="columns"
v-on="$listeners"
@ -20,15 +21,15 @@
return {
url: { list: '/sys/user/list' },
columns: [
{ title: '', align: 'center', width: '20%', widthRight: '70%', dataIndex: 'realname' },
{ title: '', align: 'center', width: '20%', dataIndex: 'username' },
{ title: '', align: 'center', width: '23%', dataIndex: 'phone' },
{ title: '', align: 'center', width: '23%', dataIndex: 'birthday' }
{ title: '', align: 'center', width: '25%', widthRight: '70%', dataIndex: 'realname' },
{ title: '', align: 'center', width: '25%', dataIndex: 'username' },
{ title: '', align: 'center', width: '20%', dataIndex: 'phone' },
{ title: '', align: 'center', width: '20%', dataIndex: 'birthday' }
],
// 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
default: {
name: '',
width: 1000,
width: 1200,
displayKey: 'realname',
returnKeys: ['id', 'username'],
queryParamText: '',

View File

@ -3,7 +3,8 @@
<a-input-search
v-model="userNames"
placeholder="请先选择用户"
disabled
readOnly
unselectable="on"
@search="onSearchDepUser">
<a-button slot="enterButton" :disabled="disabled"></a-button>
</a-input-search>

View File

@ -93,6 +93,8 @@
this.linkList.push(this.$route.fullPath)
this.activePage = this.$route.fullPath
},
mounted() {
},
watch: {
'$route': function(newRoute) {
//console.log("新的路由",newRoute)
@ -192,6 +194,7 @@
this.$message.warning('')
return
}
console.log("this.pageList ",this.pageList );
this.pageList = this.pageList.filter(item => item.fullPath !== key)
let index = this.linkList.indexOf(key)
this.linkList = this.linkList.filter(item => item !== key)

View File

@ -43,7 +43,7 @@ export default {
},
methods: {
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)
}
},

View File

@ -149,8 +149,11 @@ export default {
this.selectedRows = []
},
onClearSelected() {
// 【TESTA-262】页面清空后还能才做所选行增加 this.$emit('clearAll')
this.selectedRowKeys = []
this.selectedRows = []
this.updateSelect([], [])
this.$emit('clearAll')
},
renderMsg(h) {
const _vm = this

View File

@ -26,7 +26,7 @@ export default {
console.log('this.$route.matched', this.$route.matched)
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.$route.matched.forEach((item) => {

View File

@ -121,7 +121,7 @@
this.loadData();
//this.timerFun();
this.initWebSocket();
this.heartCheckFun();
// this.heartCheckFun();
},
destroyed: function () { // 离开页面生命周期函数
this.websocketclose();
@ -212,7 +212,7 @@
websocketOnopen: function () {
console.log("WebSocket连接成功");
//心跳检测重置
this.heartCheck.reset().start();
//this.heartCheck.reset().start();
},
websocketOnerror: function (e) {
console.log("WebSocket连接发生错误");
@ -229,7 +229,7 @@
this.loadData();
}
//心跳检测重置
this.heartCheck.reset().start();
//this.heartCheck.reset().start();
},
websocketOnclose: function (e) {
console.log("connection closed (" + e.code + ")");

View File

@ -1,17 +1,15 @@
<template>
<a-modal
class="announcementCustomModal"
<j-modal
:title="title"
:width="modelStyle.width"
:visible="visible"
:bodyStyle ="bodyStyle"
:switchFullscreen="switchFullscreen"
@cancel="handleCancel"
destroyOnClose>
<template slot="title">
<a-button icon="fullscreen" class="custom-btn" @click="handleClickToggleFullScreen"/>
</template>
>
<template slot="footer">
<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>
<a-card class="daily-article" :loading="loading">
<a-card-meta
@ -21,7 +19,7 @@
<a-divider />
<span v-html="record.msgContent" class="article-content"></span>
</a-card>
</a-modal>
</j-modal>
</template>
<script>
@ -42,6 +40,7 @@
sm: { span: 16 },
},
visible: false,
switchFullscreen: true,
loading: false,
bodyStyle:{
padding: "0",
@ -79,7 +78,7 @@
this.modelStyle.fullScreen = mode
},
toHandle(){
if(this.record.openType==='url'&&this.record.readFlag!== '1'){
if(this.record.openType==='url'){
this.visible = false;
//链接跳转
this.$router.push({path: this.record.openPage})

View File

@ -94,6 +94,7 @@
import DepartSelect from './DepartSelect'
import { mapActions, mapGetters,mapState } from 'vuex'
import { mixinDevice } from '@/utils/mixin.js'
import { getFileAccessHttpUrl } from "@/api/manage"
export default {
name: "UserMenu",
@ -157,8 +158,7 @@
...mapActions(["Logout"]),
...mapGetters(["nickname", "avatar","userInfo"]),
getAvatar(){
console.log('url = '+ window._CONFIG['staticDomainURL']+"/"+this.avatar())
return window._CONFIG['staticDomainURL']+"/"+this.avatar()
return getFileAccessHttpUrl(this.avatar())
},
handleLogout() {
const that = this
@ -229,13 +229,13 @@
color: inherit;
/deep/ .ant-select-selection {
background-color: inherit;
border: 0;
border-bottom: 1px solid white;
&__placeholder, &__field__placeholder {
color: inherit;
}
background-color: inherit;
border: 0;
border-bottom: 1px solid white;
&__placeholder, &__field__placeholder {
color: inherit;
}
}
}
/* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
/* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/

View File

@ -11,7 +11,7 @@ export const asyncRouterMap = [
name: 'dashboard',
component: TabLayout,
meta: { title: '' },
redirect: '/dashboard/workplace',
redirect: '/dashboard/analysis',
children: [
// // dashboard

View File

@ -14,13 +14,11 @@ import '@/permission' // permission control
import '@/utils/filter' // base filter
import Print from 'vue-print-nb-jeecg'
/*import '@babel/polyfill'*/
import VueApexCharts from 'vue-apexcharts'
import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
require('@jeecg/antd-online-214')
require('@jeecg/antd-online-214/dist/OnlineForm.css')
require('@jeecg/antd-online-beta220')
require('@jeecg/antd-online-beta220/dist/OnlineForm.css')
import {
ACCESS_TOKEN,
@ -41,6 +39,8 @@ import JDictSelectTag from './components/dict/index.js'
import hasPermission from '@/utils/hasPermission'
import vueBus from '@/utils/vueBus';
import JeecgComponents from '@/components/jeecg/index'
import '@/assets/less/JAreaLinkage.less'
import VueAreaLinkage from 'vue-area-linkage'
Vue.config.productionTip = false
Vue.use(Storage, config.storageOptions)
@ -50,11 +50,10 @@ Vue.use(Viser)
Vue.use(hasPermission)
Vue.use(JDictSelectTag)
Vue.use(Print)
Vue.use(VueApexCharts)
Vue.component('apexchart', VueApexCharts)
Vue.use(preview)
Vue.use(vueBus);
Vue.use(JeecgComponents);
Vue.use(VueAreaLinkage);
new Vue({
router,

View File

@ -83,7 +83,16 @@ export const JEditableTableMixin = {
requestSubTableData(url, params, tab, success) {
tab.loading = true
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) : ''
}).finally(() => {
tab.loading = false

View File

@ -4,7 +4,7 @@
* dataurl list delete deleteBatch
*/
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 { ACCESS_TOKEN } from "@/store/mutation-types"
@ -47,16 +47,18 @@ export const JeecgListMixin = {
/* 高级查询条件生效状态 */
superQueryFlag:false,
/* 高级查询条件 */
superQueryParams:""
superQueryParams: '',
/** 高级查询拼接方式 */
superQueryMatchType: 'and',
}
},
created() {
if(!this.disableMixinCreated){
console.log(' -- mixin created -- ')
this.loadData();
//初始化字典配置 在自己页面定义
this.initDictConfig();
}
if(!this.disableMixinCreated){
console.log(' -- mixin created -- ')
this.loadData();
//初始化字典配置 在自己页面定义
this.initDictConfig();
}
},
methods:{
loadData(arg) {
@ -84,22 +86,24 @@ export const JeecgListMixin = {
initDictConfig(){
console.log("--这是一个假的方法!")
},
handleSuperQuery(arg) {
handleSuperQuery(params, matchType) {
//高级查询方法
if(!arg){
if(!params){
this.superQueryParams=''
this.superQueryFlag = false
}else{
this.superQueryFlag = true
this.superQueryParams=JSON.stringify(arg)
this.superQueryParams=JSON.stringify(params)
this.superQueryMatchType = matchType
}
this.loadData()
this.loadData(1)
},
getQueryParams() {
//获取查询条件
let sqp = {}
if(this.superQueryParams){
sqp['superQueryParams']=encodeURI(this.superQueryParams)
sqp['superQueryMatchType'] = this.superQueryMatchType
}
var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
param.field = this.getQueryField();
@ -206,6 +210,10 @@ export const JeecgListMixin = {
handleToggleSearch(){
this.toggleSearchStatus = !this.toggleSearchStatus;
},
// 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
getPopupField(fields){
return fields.split(',')[0]
},
modalFormOk() {
// 新增/修改 成功时,重载列表
this.loadData();
@ -286,7 +294,7 @@ export const JeecgListMixin = {
if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
return window._CONFIG['staticDomainURL']+"/"+text
return getFileAccessHttpUrl(text)
},
/* 文件下载 */
uploadFile(text){
@ -297,7 +305,8 @@ export const JeecgListMixin = {
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['staticDomainURL']+ "/"+text);
let url = getFileAccessHttpUrl(text)
window.open(url);
},
}

View File

@ -1,78 +0,0 @@
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)
},
}
}

View File

@ -0,0 +1,26 @@
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 }

View File

@ -4,7 +4,7 @@ import store from './store'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
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"
NProgress.configure({ showSpinner: false }) // NProgress Configuration
@ -17,7 +17,7 @@ router.beforeEach((to, from, next) => {
if (Vue.ls.get(ACCESS_TOKEN)) {
/* has token */
if (to.path === '/user/login') {
next({ path: '/dashboard/workplace' })
next({ path: INDEX_MAIN_PAGE_PATH })
NProgress.done()
} else {
if (store.getters.permissionList.length === 0) {

View File

@ -1,5 +1,5 @@
import Vue from 'vue'
import { USER_INFO} from "@/store/mutation-types"
import { USER_INFO, ENHANCE_PRE } from "@/store/mutation-types"
const getters = {
device: state => state.app.device,
theme: state => state.app.theme,
@ -11,7 +11,12 @@ const getters = {
welcome: state => state.user.welcome,
permissionList: state => state.user.permissionList,
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

View File

@ -4,6 +4,7 @@ import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'
import permission from './modules/permission'
import enhance from './modules/enhance'
import getters from './getters'
Vue.use(Vuex)
@ -12,7 +13,8 @@ export default new Vuex.Store({
modules: {
app,
user,
permission
permission,
enhance
},
state: {

View File

@ -0,0 +1,37 @@
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

View File

@ -1,6 +1,6 @@
import Vue from 'vue'
import { login, logout, phoneLogin } from "@/api/login"
import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
import { login, logout, phoneLogin, thirdLogin } from "@/api/login"
import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH,UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
import { welcome } from "@/utils/util"
import { queryPermissionsByUser } from '@/api/api'
import { getAction } from '@/api/manage'
@ -71,6 +71,7 @@ const user = {
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)
Vue.ls.set(UI_CACHE_DB_DICT_DATA, result.sysAllDictItems, 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() })
@ -94,6 +95,7 @@ const user = {
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)
Vue.ls.set(UI_CACHE_DB_DICT_DATA, result.sysAllDictItems, 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() })
@ -151,10 +153,11 @@ const user = {
commit('SET_TOKEN', '')
commit('SET_PERMISSIONLIST', [])
Vue.ls.remove(ACCESS_TOKEN)
Vue.ls.remove(UI_CACHE_DB_DICT_DATA)
//console.log('logoutToken: '+ logoutToken)
logout(logoutToken).then(() => {
//var sevice = "http://"+window.location.host+"/";
//var serviceUrl = encodeURIComponent(sevice);
//let sevice = "http://"+window.location.host+"/";
//let serviceUrl = encodeURIComponent(sevice);
//window.location.href = window._CONFIG['casPrefixUrl']+"/logout?service="+serviceUrl;
resolve()
}).catch(() => {
@ -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)
})
})
},
}
}

View File

@ -14,6 +14,9 @@ export const USER_INFO = 'Login_Userinfo'
export const USER_AUTH = 'LOGIN_USER_BUTTON_AUTH'
export const SYS_BUTTON_AUTH = 'SYS_BUTTON_AUTH'
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 = {
Fluid: 'Fluid',

View File

@ -14,6 +14,7 @@ const FormTypes = {
sel_search:"sel_search",
radio:'radio',
checkbox_meta:"checkbox_meta",
input_pop:'input_pop',
slot: 'slot',
hidden: 'hidden'
@ -77,18 +78,22 @@ export function validateFormAndTables(form, cases) {
/**
*
* @param cases JEditableTable
* @param deleteTempId IDtrueIDID
* @author sunjianlei
*/
export function validateTables(cases) {
export function validateTables(cases, deleteTempId) {
if (!(cases instanceof Array)) {
throw `'validateTables''cases'${typeof cases}`
}
return new Promise((resolve, reject) => {
let tables = []
let index = 0;
if(!cases || cases.length==0){
resolve()
}
(function next() {
let vm = cases[index]
vm.getAll(true).then(all => {
vm.getAll(true, deleteTempId).then(all => {
tables[index] = all
// 判断校验是否全部完成,完成返回成功,否则继续进行下一步校验
if (++index === cases.length) {

View File

@ -9,9 +9,10 @@ export function disabledAuthFilter(code,formData) {
}
function nodeDisabledAuth(code,formData){
console.log("页面权限禁用--NODE--开始");
let permissionList = [];
try {
//console.log("页面权限禁用--NODE--开始",obj);
console.log("页面权限禁用--NODE--开始",formData);
if (formData) {
let bpmList = formData.permissionList;
permissionList = bpmList.filter(item=>item.type=='2')
@ -52,10 +53,10 @@ function nodeDisabledAuth(code,formData){
}
function globalDisabledAuth(code){
//console.log("全局页面禁用权限--Global--开始");
console.log("全局页面禁用权限--Global--开始");
var permissionList = [];
var allPermissionList = [];
let permissionList = [];
let allPermissionList = [];
//let authList = Vue.ls.get(USER_AUTH);
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
@ -72,8 +73,8 @@ function globalDisabledAuth(code){
}
}
//设置全局配置是否有命中
var gFlag = false;//禁用命中
var invalidFlag = false;//无效命中
let gFlag = false;//禁用命中
let invalidFlag = false;//无效命中
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
for (let itemG of allPermissionList) {
if(code === itemG.action){
@ -116,7 +117,7 @@ function globalDisabledAuth(code){
export function colAuthFilter(columns,pre) {
var authList = getNoAuthCols(pre);
let authList = getNoAuthCols(pre);
const cols = columns.filter(item => {
if (hasColoum(item,authList)) {
return true
@ -126,6 +127,44 @@ export function colAuthFilter(columns,pre) {
return cols
}
/**
*
* 1JEditableTable
* 2JEditableTable
* @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){
if (authList.includes(item.dataIndex)) {
return false
@ -164,6 +203,32 @@ function getNoAuthCols(pre){
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) {
if (pre == null || pre == "" || str==null|| str==""|| str.length == 0 || pre.length > str.length)
return false;

View File

@ -1,3 +1,4 @@
import { getFileAccessHttpUrl } from '@/api/manage'
const getFileName=(path)=>{
if(path.lastIndexOf("\\")>=0){
let reg=new RegExp("\\\\","g");
@ -15,7 +16,7 @@ const getFilePaths=(uploadFiles)=>{
if(!uploadFiles){
return ""
}
for(var a=0;a<uploadFiles.length;a++){
for(let a=0;a<uploadFiles.length;a++){
arr.push(uploadFiles[a].response.message)
}
if(arr && arr.length>0){
@ -30,7 +31,7 @@ const getUploadFileList=(paths)=>{
}
let fileList = [];
let arr = paths.split(",")
for(var a=0;a<arr.length;a++){
for(let a=0;a<arr.length;a++){
if(!arr[a]){
continue
}else{
@ -38,7 +39,7 @@ const getUploadFileList=(paths)=>{
uid:uidGenerator(),
name:getFileName(arr[a]),
status: 'done',
url: window._CONFIG['staticDomainURL']+"/"+arr[a],
url: getFileAccessHttpUrl(arr[a]),
response:{
status:"history",
message:arr[a]

View File

@ -0,0 +1,22 @@
/*
*
*
* 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}`
}

View File

@ -2,16 +2,16 @@ import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
const hasPermission = {
install (Vue, options) {
//console.log(options);
console.log(options);
Vue.directive('has', {
inserted: (el, binding, vnode)=>{
//console.log("页面权限控制----");
console.time()
console.log("页面权限控制----");
//console.time()
//节点权限处理,如果命中则不进行全局权限处理
if(!filterNodePermission(el, binding, vnode)){
filterGlobalPermission(el, binding, vnode);
}
console.timeEnd() //计时结束并输出时长
//console.timeEnd() //计时结束并输出时长
}
});
}

View File

@ -0,0 +1,115 @@
/**
* "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 }
}

View File

@ -5,16 +5,18 @@ import { VueAxios } from './axios'
import {Modal, notification} from 'ant-design-vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
//自动设置后台服务 baseURL (也可以手工指定写死项目名字)
let baseDomain = window._CONFIG['domianURL'];
let baseProject = baseDomain.substring(baseDomain.lastIndexOf("/"));
console.log("baseDomain= ",baseDomain)
console.log("baseProject= ",baseProject)
/**
* axios baseURL
* baseURL: '/jeecg-boot'
* vue.config.js
* @type {*|string}
*/
let apiBaseUrl = window._CONFIG['domianURL'] || "/jeecg-boot";
console.log("apiBaseUrl= ",apiBaseUrl)
// 创建 axios 实例
const service = axios.create({
//baseURL: '/jeecg-boot',
baseURL: baseProject, // api base_url
baseURL: apiBaseUrl, // api base_url
timeout: 9000 // 请求超时时间
})

View File

@ -1,5 +1,6 @@
import * as api from '@/api/api'
import { isURL } from '@/utils/validate'
import onlineCommons from '@jeecg/antd-online-beta220'
export function timeFix() {
const time = new Date()
@ -33,7 +34,7 @@ export function filterObj(obj) {
return;
}
for ( var key in obj) {
for ( let key in obj) {
if (obj.hasOwnProperty(key)
&& (obj[key] == null || obj[key] == undefined || obj[key] === '')) {
delete obj[key];
@ -49,7 +50,7 @@ export function filterObj(obj) {
* @returns {*}
*/
export function formatDate(value, fmt) {
var regPos = /^\d+(\.\d+)?$/;
let regPos = /^\d+(\.\d+)?$/;
if(regPos.test(value)){
//如果是数字
let getDate = new Date(value);
@ -100,7 +101,7 @@ let indexRouter = [{
function generateChildRouters (data) {
const routers = [];
for (var item of data) {
for (let item of data) {
let component = "";
if(item.component.indexOf("layouts")>=0){
component = "components/"+item.component;
@ -114,11 +115,33 @@ function generateChildRouters (data) {
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 = {
path: item.path,
name: item.name,
redirect:item.redirect,
component: resolve => require(['@/' + component+'.vue'], resolve),
component: componentPath,
hidden:item.hidden,
//component:()=> import(`@/views/${item.component}.vue`),
meta: {
@ -414,4 +437,44 @@ export function alwaysResolve(promise) {
reject('alwaysResolve: PromisePromise')
}
})
}
}
/**
*
*
* (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
}

View File

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

View File

@ -116,7 +116,7 @@
import PageLayout from '@/components/page/PageLayout'
import HeadInfo from '@/components/tools/HeadInfo'
import Radar from '@/components/chart/Radar'
import { getRoleList, getServiceList } from "@/api/manage"
import { getRoleList, getServiceList, getFileAccessHttpUrl } from "@/api/manage"
const DataSet = require('@antv/data-set')
@ -185,7 +185,7 @@
},
created() {
this.user = this.userInfo
this.avatar = window._CONFIG['staticDomainURL'] +"/"+ this.userInfo.avatar
this.avatar = getFileAccessHttpUrl(this.userInfo.avatar)
console.log('this.avatar :'+ this.avatar)
getRoleList().then(res => {

View File

@ -17,7 +17,7 @@
<div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
<div
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>
@ -65,37 +65,33 @@
},
data() {
return {
description: '',
description: '',
spinning:false,
//数据集
dataSource: [{
key:0,
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://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/8f22cd945be44388bacbf0b88cf86cfa.png"
}
]
},{
key:1,
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() {

View File

@ -42,11 +42,11 @@
spinning: false,
//数据集
dataSource: [
{id:'000',sort: 0,filePath: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2735633715,2749454924&fm=27&gp=0.jpg'},
{id:'111',sort: 1,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.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:'333',sort: 3,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=889120611,3801177793&fm=27&gp=0.jpg'},
{id:'444',sort: 4,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2445468140,2491956848&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://static.jeecg.com/upload/test/u27356337152749454924fm27gp0_1588149731821.jpg'},
{id:'222',sort: 2,filePath: 'https://static.jeecg.com/upload/test/u24454681402491956848fm27gp0_1588149712663.jpg'},
{id:'333',sort: 3,filePath: 'https://static.jeecg.com/upload/test/8f22cd945be44388bacbf0b88cf86cfa.png'},
{id:'444',sort: 4,filePath: 'https://static.jeecg.com/upload/test/u8891206113801177793fm27gp0_1588149704459.jpg'}
],
oldDateSource:[],
newDateSource:[],

View File

@ -50,11 +50,11 @@
children: [{
title: '1',
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',
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: '',
@ -62,11 +62,11 @@
children: [{
title: '1',
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',
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: '',
@ -74,7 +74,7 @@
children: [{
title: '1',
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:[],

View File

@ -26,7 +26,7 @@
<a-tabs defaultActiveKey="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>
</a-tab-pane>
</a-tabs>

View File

@ -6,12 +6,12 @@
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="用户名">
<j-input placeholder="请输入名称模糊查询" v-model="queryParam.name"></j-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="年龄">
<!-- <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>
@ -20,7 +20,7 @@
</a-form-item>
</a-col>
<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-range-picker v-model="queryParam.birthdayRange"
format="YYYY-MM-DD"
@ -28,56 +28,42 @@
@change="onBirthdayChange" />
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="性别">
<j-dict-select-tag v-model="queryParam.sex" placeholder="请选择性别" dictCode="sex"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="选择用户">
<j-dict-select-tag v-model="queryParam.id" placeholder="请选择用户" dictCode="demo,name,id"/>
</a-form-item>
</a-col>
</template>
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-col :md="6" :sm="24">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '' : '' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</a-col>
</span>
<a-col :md="6" :sm="24">
<!-- <template v-if="superQueryFlag">
<a-tooltip title="已有高级查询条件生效!">
<button :disabled="false" class="ant-btn ant-btn-primary" @click="superQuery">
<a-icon type="appstore" theme="twoTone" spin="true"></a-icon>
<span></span>
</button>
</a-tooltip>
</template>
<a-button v-else type="primary" @click="superQuery" icon="filter"></a-button>
-->
<!-- -->
<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-form>
</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 type="primary" icon="plus" @click="jump"></a-button>
<a-button type="primary" icon="plus" @click="onetomany"></a-button>
<a-button type="primary" icon="download" @click="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-button type="primary" icon="import"></a-button>
</a-upload>
<!-- -->
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
@ -112,7 +98,7 @@
</a-row>
</a-checkbox-group>
</template>
<a><a-icon type="setting" /></a>
<a><a-icon type="setting" /></a>
</a-popover>
</span>
</div>
@ -178,25 +164,27 @@
import JSuperQuery from '@/components/jeecg/JSuperQuery.vue';
import JInput from '@/components/jeecg/JInput.vue';
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 Vue from 'vue'
import { filterObj } from '@/utils/util';
//高级查询modal需要参数
const superQueryFieldList=[{
type:"date",
value:"birthday",
text:"生日"
},{
type:"string",
value:"name",
text:"用户名"
},{
type:"int",
value:"age",
text:"年龄"
}]
const superQueryFieldList=[
{
type: "string",
value: "name",
text: "用户名"
}, {
type: "int",
value: "age",
text: "年龄"
}, {
type: "date",
value: "birthday",
text: "生日"
}
]
export default {
name: "JeecgDemoList",
mixins:[JeecgListMixin],
@ -208,7 +196,7 @@
},
data() {
return {
description: '',
description: '',
//字典数组缓存
sexDictOptions: [],
importExcelUrl:`${window._CONFIG['domianURL']}/test/jeecgDemo/importExcel`,
@ -249,7 +237,7 @@
dataIndex: 'sex',
customRender: (text) => {
//字典值替换通用方法
return filterDictText(this.sexDictOptions, text);
return filterDictTextByCache('sex', text);
}
},
{
@ -293,12 +281,11 @@
},
methods: {
getQueryParams(){
console.log(this.queryParam.birthdayRange)
//高级查询器
let sqp = {}
if(this.superQueryParams){
sqp['superQueryParams']=encodeURI(this.superQueryParams)
sqp['superQueryMatchType'] = this.superQueryMatchType
}
var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
@ -380,38 +367,5 @@
}
</script>
<style scoped>
.ant-card-body .table-operator {
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
/** Button按钮间距 */
.ant-btn {
margin-left: 3px
}
@import '~@assets/less/common.less';
</style>

View File

@ -28,7 +28,7 @@
</div>
</template>
<template v-else>
("选择文件""扫描上传")
("选择文件""扫描上传")
</template>
</a-col>
</a-row>

View File

@ -1,5 +1,5 @@
<template>
<a-card :bordered="false" style="height:100%">
<a-card :bordered="false" style="height:100%;padding-bottom:200px; ">
<div class="table-page-search-wrapper">
<a-form layout="inline" :form="form">
@ -10,7 +10,7 @@
<a-col :span="12">
<a-form-item label="性别">
<j-dict-select-tag v-model="formData.sex" title="性别" dictCode="sex" placeholder="请选择性别"/>
<!-- <j-dict-select-tag title="性别" dictCode="sex" disabled/>-->
<!-- <j-dict-select-tag title="性别" dictCode="sex" disabled/>-->
</a-form-item>
</a-col>
<a-col :span="12">{{ formData.sex}}</a-col>
@ -36,6 +36,47 @@
<a-col :span="12">{{ formData.user2}}</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="字典搜索(同步)">
<j-search-select-tag placeholder="请做出你的选择" v-model="formData.searchValue" :dictOptions="searchOptions">
</j-search-select-tag>
</a-form-item>
</a-col>
<a-col :span="12">{{ formData.searchValue}}</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="字典搜索(异步)">
<j-search-select-tag
placeholder="请做出你的选择"
v-model="formData.asyncSelectValue"
dict="sys_depart,depart_name,id"
:async="true">
</j-search-select-tag>
</a-form-item>
</a-col>
<a-col :span="12">{{ formData.asyncSelectValue}}</a-col>
</a-row>
<!-- JMultiSelectTag -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="字典下拉(多选)">
<j-multi-select-tag
v-model="formData.selMuti"
dictCode="sex"
placeholder="请选择">
</j-multi-select-tag>
</a-form-item>
</a-col>
<a-col :span="12">(v-model){{ formData.selMuti }}</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
@ -79,12 +120,22 @@
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="选择角色">
<j-select-role v-model="formData.selectRole"/>
<j-select-role v-model="formData.selectRole" @change="changeMe"/>
</a-form-item>
</a-col>
<a-col :span="12">{{ formData.selectRole}}</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="选择职务">
<j-select-position v-model="formData.selectPosition" />
</a-form-item>
</a-col>
<a-col :span="12">{{ formData.selectPosition}}</a-col>
</a-row>
<!-- JCheckbox -->
<a-row :gutter="24">
<a-col :span="12">
@ -142,16 +193,6 @@
<a-col :span="12">{{ jellipsis.value }}</a-col>
</a-row>
<!-- JGraphicCode -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="验证码">
<j-graphic-code @success="generateCode"/>
</a-form-item>
</a-col>
<a-col :span="12">{{ jgraphicCode.value }}</a-col>
</a-row>
<!-- JSlider -->
<a-row :gutter="24">
<a-col :span="12">
@ -200,16 +241,10 @@
</a-col>
</a-row>
<!-- JSuperQuery -->
<!-- JTreeSelect -->
<!-- JTreeTable -->
<!-- JUpload. -->
<!-- JImportModal -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="树字典">
<j-tree-dict v-model="formData.treeDict" placeholder="请选择树字典" parentCode="A01" />
<j-tree-dict v-model="formData.treeDict" placeholder="请选择树字典" parentCode="B01" />
</a-form-item>
</a-col>
<a-col :span="12">(v-model){{ formData.treeDict }}</a-col>
@ -227,7 +262,7 @@
/>
</a-form-item>
</a-col>
<a-col :spapn="12">(v-model){{ formData.treeSelect }}</a-col>
<a-col :span="12">(v-model){{ formData.treeSelect }}</a-col>
</a-row>
<a-row :gutter="24">
@ -243,7 +278,17 @@
/>
</a-form-item>
</a-col>
<a-col :spapn="12">(v-model){{ formData.treeSelectMultiple }}</a-col>
<a-col :span="12">(v-model){{ formData.treeSelectMultiple }}</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="分类字典树">
<j-category-select v-model="formData.selectCategory" pcode="A01"/>
</a-form-item>
</a-col>
<a-col :span="12">(v-model){{ formData.selectCategory }}</a-col>
</a-row>
<!-- VueCron -->
@ -267,19 +312,38 @@
<a-col :span="12">
<a-form-item label="高级查询(自定义按钮)">
<j-super-query :fieldList="superQuery.fieldList">
<!-- -->
<a-button type="primary" ghost icon="clock-circle"></a-button>
<!--
v-slot:button
isActive:
isMobile:
open:
reset:
-->
<template v-slot:button="{isActive,isMobile,open,reset}">
<!-- -->
<a-button v-if="!isActive" type="primary" ghost icon="clock-circle" @click="open()"></a-button>
<!-- -->
<a-button-group v-else>
<a-button type="primary" ghost @click="open()">
<a-icon type="plus-circle" spin/>
<span></span>
</a-button>
<a-button v-if="isMobile" type="primary" ghost icon="delete" @click="reset()"/>
</a-button-group>
</template>
</j-super-query>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="图片上传">
<j-image-upload v-model="imgList"></j-image-upload>
</a-form-item>
</a-col>
<a-col :spapn="12">(v-model){{ imgList }}</a-col>
<a-col :span="12">(v-model){{ imgList }}</a-col>
</a-row>
<a-row :gutter="24" style="margin-top: 65px;margin-bottom:50px;">
<a-col :span="12">
@ -287,12 +351,80 @@
<j-upload v-model="fileList"></j-upload>
</a-form-item>
</a-col>
<a-col :spapn="12">
<a-col :span="12">
(v-model)
<j-ellipsis :value="fileList" :length="30" v-if="fileList.length>0"/>
</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="特殊查询组件">
<a-row>
<a-col :span="16">
<j-input v-model="formData.jInput" :type="jInput.type"/>
</a-col>
<a-col :span="3" style="text-align: right;" ></a-col>
<a-col :span="5">
<a-select v-model="jInput.type" :options="jInput.options"></a-select>
</a-col>
</a-row>
</a-form-item>
</a-col>
<a-col :span="12">(v-model){{ formData.jInput }}</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="15">
<a-form-item label="MarkdownEditor" style="min-height: 300px">
<j-markdown-editor v-model="content"></j-markdown-editor>
</a-form-item>
</a-col>
<a-col :span="9">
(v-model){{ content }}
</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="省市县级联">
<j-area-linkage v-model="formData.areaLinkage1" type="cascader"/>
</a-form-item>
</a-col>
<a-col :span="12">(v-model){{ formData.areaLinkage1 }}</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="省市县级联">
<j-area-linkage v-model="formData.areaLinkage2" type="select"/>
</a-form-item>
</a-col>
<a-col :span="12">(v-model){{ formData.areaLinkage2 }}</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="功能示例:关闭当前页面">
<a-button type="primary" @click="handleCloseCurrentPage"></a-button>
</a-form-item>
</a-col>
</a-row>
<!-- JPopup -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="JPopup示例">
<j-popup v-model="formData.jPopup" code="demo" field="name" orgFields="name" destFields="name"/>
</a-form-item>
</a-col>
<a-col :span="12">(v-model){{ formData.jPopup }}</a-col>
</a-row>
</a-form>
</div>
@ -311,7 +443,6 @@
import JDate from '@/components/jeecg/JDate'
import JEditor from '@/components/jeecg/JEditor'
import JEllipsis from '@/components/jeecg/JEllipsis'
import JGraphicCode from '@/components/jeecg/JGraphicCode'
import JSlider from '@/components/jeecg/JSlider'
import JSelectMultiple from '@/components/jeecg/JSelectMultiple'
import JTreeDict from "../../components/jeecg/JTreeDict.vue";
@ -320,10 +451,23 @@
import JSuperQuery from '@/components/jeecg/JSuperQuery'
import JUpload from '@/components/jeecg/JUpload'
import JImageUpload from '@/components/jeecg/JImageUpload'
import JSelectPosition from '@comp/jeecgbiz/JSelectPosition'
import JCategorySelect from '@comp/jeecg/JCategorySelect'
import JMultiSelectTag from '@comp/dict/JMultiSelectTag'
import JInput from '@comp/jeecg/JInput'
import JAreaLinkage from '@comp/jeecg/JAreaLinkage'
import JMarkdownEditor from '@/components/jeecg/JMarkdownEditor/index'
import JSearchSelectTag from '@/components/dict/JSearchSelectTag'
export default {
name: 'SelectDemo',
inject:['closeCurrent'],
components: {
JMarkdownEditor,
JAreaLinkage,
JInput,
JCategorySelect,
JSelectPosition,
JImageUpload,
JUpload,
JTreeDict,
@ -334,14 +478,19 @@
JSelectRole,
JCheckbox,
JCodeEditor,
JDate, JEditor, JEllipsis, JGraphicCode, JSlider, JSelectMultiple,
JCron, JTreeSelect, JSuperQuery
JDate, JEditor, JEllipsis, JSlider, JSelectMultiple,
JCron, JTreeSelect, JSuperQuery, JMultiSelectTag,
JSearchSelectTag
},
data() {
return {
selectList: [],
selectedDepUsers: '',
formData: {},
formData: {
areaLinkage1: '110105',
areaLinkage2: '140221',
sex: 1
},
form: this.$form.createForm(this),
departId: '4f1765520d6346f9bd9c79e2479e5b12,57197590443c44f083d42ae24ef26a2c',
userIds: 'admin',
@ -370,9 +519,6 @@ sayHi('hello, world!')`
jellipsis: {
value: ''
},
jgraphicCode: {
value: ''
},
jslider: {
value: false
},
@ -396,11 +542,41 @@ sayHi('hello, world!')`
fieldList: [
{ type: 'input', value: 'name', text: '', },
{ type: 'select', value: 'sex', text: '', dictCode: 'sex' },
{ type: 'number', value: 'age', text: '', }
{ type: 'number', value: 'age', text: '', },
{
type: 'select', value: 'hobby', text: '',
options: [
{ label: '', value: '1' },
{ label: '', value: '2' },
{ label: '', value: '3' },
{ label: '', value: '4' },
]
},
]
},
fileList:[],
imgList:[],
jInput: {
type: 'like',
options: [
{ value: 'like', label: 'like' },
{ value: 'ne', label: 'ne' },
{ value: 'ge', label: 'ge' },
{ value: 'le', label: 'le)' },
],
},
content: '',
searchOptions:[{
text:"选项一",
value:"1"
},{
text:"选项二",
value:"2"
},{
text:"选项三",
value:"3"
}],
}
},
computed: {
@ -419,6 +595,9 @@ sayHi('hello, world!')`
getDepartIdValue() {
return this.form.getFieldValue('departId')
},
changeMe() {
console.log('you so ... , change Me')
},
selectOK: function(data) {
this.selectList = data
},
@ -437,9 +616,6 @@ sayHi('hello, world!')`
onSearchDepUserCallBack(selectedDepUsers) {
this.selectedDepUsers = selectedDepUsers
},
generateCode(value) {
this.jgraphicCode.value = value.toLowerCase()
},
handleJSliderSuccess(value) {
this.jslider.value = value
},
@ -447,7 +623,14 @@ sayHi('hello, world!')`
this.$nextTick(() => {
this.form.cronExpression = data;
})
}
},
handleCloseCurrentPage() {
// 注意:以下代码必须存在
// inject:['closeCurrent'],
this.closeCurrent()
},
}
}
</script>

View File

@ -33,6 +33,7 @@
<script>
import { getAction } from '@/api/manage'
export default {
props: ['sex','name'],
data () {
return {
formLayout: 'horizontal',
@ -63,11 +64,25 @@
},
},
created (){
console.log('============= online href common props ============= ');
console.log('props sex: ',this.sex);
console.log('props name: ',this.name);
getAction('/api/area').then((res) => {
console.log("------------")
console.log(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>

View File

@ -25,7 +25,7 @@
@selectRowChange="handleSelectRowChange">
<template v-slot:action="props">
<a @click="handleDelete(props)">{{ props.text }}</a>
<a @click="handleDelete(props)"></a>
</template>
</j-editable-table>
@ -154,6 +154,8 @@
type: FormTypes.inputNumber,
defaultValue: 32,
placeholder: '${title}',
// 是否是统计列,只有 inputNumber 才能设置统计列
statistics: true,
validateRules: [{ required: true, message: '${title}' }]
},
{
@ -166,6 +168,15 @@
placeholder: '${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: '',
key: 'isNull',
@ -175,6 +186,16 @@
customValue: ['Y', 'N'], // true ,false
defaultChecked: false
},
{
type: FormTypes.popup,
key: 'popup',
title: 'JPopup',
width: '180px',
popupCode: 'demo',
field: 'name',
orgFields: 'name',
destFields: 'name'
},
{
title: '',
key: 'action',
@ -182,7 +203,6 @@
width: '100px',
type: FormTypes.slot,
slotName: 'action',
defaultValue: ''
}
],

View File

@ -624,7 +624,7 @@
}
},
callback (key) {
console.log(key)
//console.log(key)
}
}
}

View File

@ -160,7 +160,6 @@
add: "/test/order/addCustomer",
edit: "/test/order/editCustomer",
fileUpload: window._CONFIG['domianURL'] + "/sys/common/upload",
imgerver: window._CONFIG['staticDomainURL'],
getOrderCustomerList: "/test/order/listOrderCustomerByMainId",
},
validatorRules: {
@ -246,7 +245,11 @@
let formData = Object.assign(this.model, values);
console.log(formData);
formData.orderId = this.orderId;
formData.idcardPic = this.fileList;
if(this.fileList != '') {
formData.idcardPic = this.fileList;
}else{
formData.idcardPic = '';
}
httpAction(httpurl, formData, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
@ -278,36 +281,6 @@
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>

View File

@ -1,391 +0,0 @@
<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.tableName"></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="doCgformButton" type="primary" icon="highlight"></a-button>
<a-button @click="doEnhanceJs" type="primary" icon="strikethrough">JS</a-button>
<a-button @click="doEnhanceSql" type="primary" icon="filter">SQL</a-button>
<a-button @click="doEnhanceJava" type="primary" icon="tool">Java</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>
<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">
<template slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
<a-icon type="down"/>
</a>
<a-menu slot="overlay">
<a-menu-item>
<a @click="goPageOnline(record)"></a>
</a-menu-item>
<a-menu-item>
<a @click="handleOnlineUrlShow(record)"></a>
</a-menu-item>
<a-menu-item>
<a @click="handleRemoveRecord(record.id)"></a>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<template slot="dbsync" slot-scope="text">
<span v-if="text==='Y'" style="color:limegreen"></span>
<span v-if="text==='N'" style="color:red"></span>
</template>
</a-table>
</div>
<!-- table-end -->
<!-- -->
<onl-cgform-head-modal ref="modalForm" @ok="modalFormOk" :action-button="false"></onl-cgform-head-modal>
<!-- online -->
<a-modal
:title="onlineUrlTitle"
:visible="onlineUrlVisible"
@cancel="handleOnlineUrlClose">
<template slot="footer">
<a-button @click="handleOnlineUrlClose"></a-button>
<a-button type="primary" class="copy-this-text" :data-clipboard-text="onlineUrl" @click="onCopyUrl"></a-button>
</template>
<p>{{ onlineUrl }}</p>
</a-modal>
<enhance-js ref="ehjs"></enhance-js>
<enhance-sql ref="ehsql"></enhance-sql>
<enhance-java ref="ehjava"></enhance-java>
<trans-db2-online ref="transd2o" @ok="transOk"></trans-db2-online>
<onl-cgform-button-list ref="btnList"></onl-cgform-button-list>
</a-card>
</template>
<script>
import { deleteAction, postAction,getAction } from '@/api/manage'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Clipboard from 'clipboard'
import { filterObj } from '@/utils/util';
export default {
name: 'OnlCgformHeadList',
mixins: [JeecgListMixin],
components: {
},
data() {
return {
description: 'Online',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function(t, r, index) {
return parseInt(index) + 1
}
},
{
title: '',
align: 'center',
dataIndex: 'tableName'
},
{
title: '',
align: 'center',
dataIndex: 'tableTxt'
},
{
title: '',
align: 'center',
dataIndex: 'tableVersion'
},
{
title: '',
align: 'center',
dataIndex: 'copyVersion'
},
{
title: '',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
],
url: {
list: '/online/cgform/head/list',
delete: '/online/cgform/head/delete',
deleteBatch: '/online/cgform/head/deleteBatch',
removeRecord: '/online/cgform/head/removeRecord',
},
tableTypeDictOptions: [],
sexDictOptions: [],
syncModalVisible: false,
syncFormId: '',
synMethod: 'normal',
syncLoading: false,
onlineUrlTitle: '',
onlineUrlVisible: false,
onlineUrl: '',
selectedRowKeys: [],
selectedRows: [],
physicId:""
}
},
watch: {
'$route'() {
this.loadData()
}
},
methods: {
getQueryParams() {
//获取查询条件
var param = Object.assign({}, this.queryParam, this.isorter ,this.filters);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
param.copyType = 1;
param.physicId = this.physicId;
return filterObj(param);
},
loadData(arg) {
if(!this.$route.params.code){
return false
}
this.physicId = this.$route.params.code
if(!this.url.list){
this.$message.error("请设置url.list属性!")
return
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
this.loading = true;
getAction(this.url.list, params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
if(res.code===510){
this.$message.warning(res.message)
}
this.loading = false;
})
},
goPageOnline(rd) {
if(rd.isTree=='Y'){
this.$router.push({ path: '/online/cgformTreeList/' + rd.id })
}else{
this.$router.push({ path: '/online/cgformList/' + rd.id })
}
},
handleOnlineUrlClose() {
this.onlineUrlTitle = ''
this.onlineUrlVisible = false
},
handleOnlineUrlShow(record) {
if(record.isTree=='Y'){
this.onlineUrl = `/online/cgformTreeList/${record.id}`
}else{
this.onlineUrl = `/online/cgformList/${record.id}`
}
this.onlineUrlVisible = true
this.onlineUrlTitle = '[' + record.tableTxt + ']'
},
handleRemoveRecord(id) {
let that = this
this.$confirm({
title: '?',
onOk() {
deleteAction(that.url.removeRecord, { id: id }).then((res) => {
if (res.success) {
that.$message.success('')
that.loadData()
} else {
that.$message.warning(res.message)
}
})
},
onCancel() {
}
})
},
doEnhanceJs() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
this.$refs.ehjs.show(this.selectedRowKeys[0])
},
doEnhanceSql() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
this.$refs.ehsql.show(this.selectedRowKeys[0])
},
doEnhanceJava() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
this.$refs.ehjava.show(this.selectedRowKeys[0])
},
doCgformButton() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
this.$refs.btnList.show(this.selectedRowKeys[0])
//this.$router.push({ path: '/online/cgformButton/' + this.selectedRowKeys[0] })
},
importOnlineForm() {
this.$refs.transd2o.show()
},
transOk() {
this.loadData()
},
onSelectChange(keys, rows) {
this.selectedRowKeys = keys
this.selectedRows = rows
},
onCopyUrl(){
var clipboard = new Clipboard('.copy-this-text')
clipboard.on('success', () => {
clipboard.destroy()
this.$message.success('')
this.handleOnlineUrlClose()
})
clipboard.on('error', () => {
this.$message.error('')
clipboard.destroy()
})
},
showMyCopyInfo(id){
console.log("查看复制表单的信息",id)
},
copyConfig(id){
postAction(`${this.url.copyOnline}?code=${id}`).then(res=>{
if(res.success){
this.$message.success("复制成功")
this.loadData()
}else{
this.$message.error("复制失败>>"+res.message)
}
})
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<style lang="less">
.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
}
.valid-error-cust{
.ant-select-selection{
border:2px solid #f5222d;
}
}
</style>

View File

@ -1,493 +0,0 @@
<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.tableName"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="表类型">
<j-dict-select-tag dictCode="cgform_table_type" v-model="queryParam.tableType"/>
</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.tableTxt"></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-button @click="doCgformButton" type="primary" icon="highlight"></a-button>
<a-button @click="doEnhanceJs" type="primary" icon="strikethrough">JS</a-button>
<a-button @click="doEnhanceSql" type="primary" icon="filter">SQL</a-button>
<a-button @click="doEnhanceJava" type="primary" icon="tool">Java</a-button>
<a-button @click="importOnlineForm" type="primary" icon="database"></a-button>
<a-button @click="goGenerateCode" type="primary" icon="database"></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>
<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">
<template 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 v-if="record.isDbSynch!='Y'">
<a @click="openSyncModal(record.id)"></a>
</a-menu-item>
<template v-if="record.isDbSynch=='Y' && record.tableType !== 3">
<a-menu-item>
<a @click="goPageOnline(record)"></a>
</a-menu-item>
<a-menu-item>
<a @click="handleOnlineUrlShow(record)"></a>
</a-menu-item>
</template>
<a-menu-item>
<a @click="copyConfig(record.id)"></a>
</a-menu-item>
<a-menu-item v-if="record.hascopy==1">
<a @click="showMyCopyInfo(record.id)"></a>
</a-menu-item>
<a-menu-item>
<a @click="handleRemoveRecord(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>
</template>
<template slot="dbsync" slot-scope="text">
<span v-if="text==='Y'" style="color:limegreen"></span>
<span v-if="text==='N'" style="color:red"></span>
</template>
</a-table>
</div>
<!-- table-end -->
<!-- -->
<onl-cgform-head-modal ref="modalForm" @ok="modalFormOk"></onl-cgform-head-modal>
<!-- -->
<a-modal
:width="500"
:height="300"
title="同步数据库"
:visible="syncModalVisible"
@cancel="handleCancleDbSync"
style="top:5%;height: 95%;">
<template slot="footer">
<a-button @click="handleCancleDbSync"></a-button>
<a-button type="primary" :loading="syncLoading" @click="handleDbSync">
</a-button>
</template>
<a-radio-group v-model="synMethod">
<a-radio style="display: block;width: 30px;height: 30px" value="normal">()</a-radio>
<a-radio style="display: block;width: 30px;height: 30px" value="force">(,)</a-radio>
</a-radio-group>
</a-modal>
<!-- online -->
<a-modal
:title="onlineUrlTitle"
:visible="onlineUrlVisible"
@cancel="handleOnlineUrlClose">
<template slot="footer">
<a-button @click="handleOnlineUrlClose"></a-button>
<a-button type="primary" class="copy-this-text" :data-clipboard-text="onlineUrl" @click="onCopyUrl"></a-button>
</template>
<p>{{ onlineUrl }}</p>
</a-modal>
<enhance-js ref="ehjs"></enhance-js>
<enhance-sql ref="ehsql"></enhance-sql>
<enhance-java ref="ehjava"></enhance-java>
<trans-db2-online ref="transd2o" @ok="transOk"></trans-db2-online>
<code-generator ref="cg"></code-generator>
<onl-cgform-button-list ref="btnList"></onl-cgform-button-list>
</a-card>
</template>
<script>
import { initDictOptions, filterDictText } from '@/components/dict/JDictSelectUtil'
import { deleteAction, postAction } from '@/api/manage'
import JDictSelectTag from '../../../../components/dict/JDictSelectTag.vue'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Clipboard from 'clipboard'
import { filterObj } from '@/utils/util';
export default {
name: 'OnlCgformHeadList',
mixins: [JeecgListMixin],
components: {
JDictSelectTag,
},
data() {
return {
description: 'Online',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function(t, r, index) {
return parseInt(index) + 1
}
},
{
title: '',
align: 'center',
dataIndex: 'tableType',
customRender: (text, record) => {
let tbTypeText = filterDictText(this.tableTypeDictOptions, `${text}`)
if(record.isTree === 'Y'){
tbTypeText+='()'
}
return tbTypeText;
}
},
{
title: '',
align: 'center',
dataIndex: 'tableName'
},
{
title: '',
align: 'center',
dataIndex: 'tableTxt'
},
{
title: '',
align: 'center',
dataIndex: 'tableVersion'
},
{
title: '',
align: 'center',
dataIndex: 'isDbSynch',
scopedSlots: { customRender: 'dbsync' }
},
{
title: '',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
],
url: {
list: '/online/cgform/head/list',
delete: '/online/cgform/head/delete',
deleteBatch: '/online/cgform/head/deleteBatch',
doDbSynch: '/online/cgform/api/doDbSynch/',
removeRecord: '/online/cgform/head/removeRecord',
copyOnline: '/online/cgform/head/copyOnline'
},
tableTypeDictOptions: [],
sexDictOptions: [],
syncModalVisible: false,
syncFormId: '',
synMethod: 'normal',
syncLoading: false,
onlineUrlTitle: '',
onlineUrlVisible: false,
onlineUrl: '',
selectedRowKeys: [],
selectedRows: []
}
},
created() {
//初始化字典 - 表类型
initDictOptions('cgform_table_type').then((res) => {
if (res.success) {
this.tableTypeDictOptions = res.result
}
})
},
methods: {
doDbSynch(id) {
postAction(this.url.doDbSynch + id, { synMethod: '1' }).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.loadData()
} else {
this.$message.warning(res.message)
}
})
},
getQueryParams() {
//获取查询条件
var param = Object.assign({}, this.queryParam, this.isorter ,this.filters);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
param.copyType = 0;
return filterObj(param);
},
handleCancleDbSync() {
this.syncModalVisible = false
},
handleDbSync() {
this.syncLoading = true
postAction(this.url.doDbSynch + this.syncFormId + '/' + this.synMethod).then((res) => {
this.syncModalVisible = false
this.syncLoading = false
if (res.success) {
this.$message.success(res.message)
this.loadData()
} else {
this.$message.warning(res.message)
}
})
setTimeout(()=>{
if(this.syncLoading){
this.syncModalVisible = false
this.syncLoading = false
this.$message.success("网络延迟,已自动刷新!")
this.loadData()
}
},10000)
},
openSyncModal(id) {
this.syncModalVisible = true
this.syncLoading = false
this.syncFormId = id
},
goPageOnline(rd) {
if(rd.themeTemplate === 'erp'){
this.$router.push({ path: '/online/cgformErpList/' + rd.id })
}else{
if(rd.isTree=='Y'){
this.$router.push({ path: '/online/cgformTreeList/' + rd.id })
}else{
this.$router.push({ path: '/online/cgformList/' + rd.id })
}
}
},
handleOnlineUrlClose() {
this.onlineUrlTitle = ''
this.onlineUrlVisible = false
},
handleOnlineUrlShow(record) {
if(record.isTree=='Y'){
this.onlineUrl = `/online/cgformTreeList/${record.id}`
}else{
this.onlineUrl = `/online/cgformList/${record.id}`
}
this.onlineUrlVisible = true
this.onlineUrlTitle = '[' + record.tableTxt + ']'
},
handleRemoveRecord(id) {
let that = this
this.$confirm({
title: '?',
onOk() {
deleteAction(that.url.removeRecord, { id: id }).then((res) => {
if (res.success) {
that.$message.success('')
that.loadData()
} else {
that.$message.warning(res.message)
}
})
},
onCancel() {
}
})
},
doEnhanceJs() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
this.$refs.ehjs.show(this.selectedRowKeys[0])
},
doEnhanceSql() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
this.$refs.ehsql.show(this.selectedRowKeys[0])
},
doEnhanceJava() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
this.$refs.ehjava.show(this.selectedRowKeys[0])
},
doCgformButton() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
this.$refs.btnList.show(this.selectedRowKeys[0])
//this.$router.push({ path: '/online/cgformButton/' + this.selectedRowKeys[0] })
},
importOnlineForm() {
this.$refs.transd2o.show()
},
transOk() {
this.loadData()
},
goGenerateCode() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('')
return
}
let row = this.selectedRows[0]
if (!row.isDbSynch || row.isDbSynch == 'N') {
this.$message.warning('!')
return
}
if (row.tableType == 3) {
this.$message.warning('')
return
}
this.$refs.cg.show(this.selectedRowKeys[0])
},
onSelectChange(keys, rows) {
this.selectedRowKeys = keys
this.selectedRows = rows
},
onCopyUrl(){
var clipboard = new Clipboard('.copy-this-text')
clipboard.on('success', () => {
clipboard.destroy()
this.$message.success('')
this.handleOnlineUrlClose()
})
clipboard.on('error', () => {
this.$message.error('')
clipboard.destroy()
})
},
showMyCopyInfo(id){
this.$router.push({ path: '/online/copyform/' + id })
},
copyConfig(id){
postAction(`${this.url.copyOnline}?code=${id}`).then(res=>{
if(res.success){
this.$message.success("复制成功")
this.loadData()
}else{
this.$message.error("复制失败>>"+res.message)
}
})
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<style lang="less">
.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
}
.valid-error-cust{
.ant-select-selection{
border:2px solid #f5222d;
}
}
</style>

View File

@ -1,41 +0,0 @@
/**
* 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;
}
}

View File

@ -1,827 +0,0 @@
<template>
<a-card :bordered="false" style="height: 100%">
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchByquery">
<a-row :gutter="24" v-if="queryInfo && queryInfo.length>0">
<template v-for="(item,index) in queryInfo">
<template v-if=" item.hidden==='1' ">
<a-col v-if="item.view=='datetime'" :md="12" :sm="16" :key=" 'query'+index " v-show="toggleSearchStatus">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
<a-col v-else :md="6" :sm="8" :key=" 'query'+index " v-show="toggleSearchStatus">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
</template>
<template v-else>
<a-col v-if="item.view=='datetime'" :md="12" :sm="16" :key=" 'query'+index ">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
<a-col v-else :md="6" :sm="8" :key=" 'query'+index ">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
</template>
</template>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchByquery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '' : '' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- -->
<div class="table-operator">
<a-button v-if="buttonSwitch.add" @click="handleAdd" type="primary" icon="plus"></a-button>
<a-button v-if="buttonSwitch.import" @click="handleImportXls" type="primary" icon="upload"></a-button>
<a-button v-if="buttonSwitch.export" @click="handleExportXls" type="primary" icon="download"></a-button>
<template v-if="cgButtonList && cgButtonList.length>0" v-for="(item,index) in cgButtonList">
<a-button
v-if=" item.optType=='js' "
:key=" 'cgbtn'+index "
@click="cgButtonJsHandler(item.buttonCode)"
type="primary"
:icon="item.buttonIcon">
{{ item.buttonName }}
</a-button>
<a-button
v-else-if=" item.optType=='action' "
:key=" 'cgbtn'+index "
@click="cgButtonActionHandler(item.buttonCode)"
type="primary"
:icon="item.buttonIcon">
{{ item.buttonName }}
</a-button>
</template>
<!-- -->
<j-super-query
ref="superQuery"
:fieldList="superQuery.fieldList"
:saveCode="$route.fullPath"
:loading="table.loading"
@handleSuperQuery="handleSuperQuery"/>
<a-button
v-if="buttonSwitch.batch_delete"
@click="handleDelBatch"
v-show="table.selectedRowKeys.length > 0"
ghost
type="primary"
icon="delete"></a-button>
</div>
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
&nbsp;<a style="font-weight: 600">{{ table.selectedRowKeys.length }}</a>&nbsp;&nbsp;
<a style="margin-left: 24px" @click="onClearSelected"></a>
</div>
<a-table
ref="cgformAutoList"
bordered
size="middle"
rowKey="id"
:columns="table.columns"
:dataSource="table.dataSource"
:pagination="table.pagination"
:loading="table.loading"
:rowSelection="rowSelectionConfig"
@change="handleTableChange"
:scroll="table.scroll"
style="min-height: 300px">
<!-- href -->
<template
v-for="field of fieldHrefSlots"
:slot="field.slotName"
slot-scope="text, record"
>
<a @click="handleClickFieldHref(field,record)">{{ text }}</a>
</template>
<template slot="dateSlot" slot-scope="text">
<span>{{ getFormatDate(text) }}</span>
</template>
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;"></span>
<img v-else :src="getImgView(text)" height="25px" alt="图片不存在" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;"></span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="downloadRowFile(text)">
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<template v-if="hasBpmStatus">
<template v-if="record.bpm_status == '1'||record.bpm_status == ''|| record.bpm_status == null">
<template v-if="buttonSwitch.update">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
</template>
</template>
</template>
<template v-else>
<template v-if="buttonSwitch.update">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
</template>
</template>
<a-dropdown>
<a class="ant-dropdown-link">
<a-icon type="down" />
</a>
<a-menu slot="overlay">
<a-menu-item v-if="buttonSwitch.detail">
<a href="javascript:;" @click="handleDetail(record)"></a>
</a-menu-item>
<template v-if="hasBpmStatus">
<template v-if="record.bpm_status == '1'||record.bpm_status == ''|| record.bpm_status == null">
<a-menu-item v-if="buttonSwitch.delete">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a></a>
</a-popconfirm>
</a-menu-item>
</template>
</template>
<template v-else>
<a-menu-item v-if="buttonSwitch.delete">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a></a>
</a-popconfirm>
</a-menu-item>
</template>
<template v-if="cgButtonLinkList && cgButtonLinkList.length>0" v-for="(btnItem,btnIndex) in cgButtonLinkList">
<a-menu-item :key=" 'cgbtnLink'+btnIndex " v-if="showLinkButton(btnItem,record)">
<a href="javascript:void(0);" @click="cgButtonLinkHandler(record,btnItem.buttonCode,btnItem.optType)">
<a-icon v-if="btnItem.buttonIcon" :type="btnItem.buttonIcon" />
{{ btnItem.buttonName }}
</a>
</a-menu-item>
</template>
</a-menu>
</a-dropdown>
</span>
</a-table>
<onl-cgform-auto-modal @success="handleFormSuccess" ref="modal" :code="code" @schema="handleGetSchema" />
<j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal>
<!-- Href -->
<a-modal v-bind="hrefComponent.model" v-on="hrefComponent.on">
<component :is="hrefComponent.is" v-bind="hrefComponent.params"/>
</a-modal>
</div>
</a-card>
</template>
<script>
import { HrefJump } from '@/mixins/OnlAutoListMixin'
import { postAction,getAction,deleteAction,downFile } from '@/api/manage'
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import { cloneObject, filterObj } from '@/utils/util'
import JImportModal from '@/components/jeecg/JImportModal'
import JSuperQuery from '@comp/jeecg/JSuperQuery'
import ButtonExpHandler from './ButtonExpHandler'
export default {
name: 'OnlCgFormAutoList',
mixins: [HrefJump],
components: {
JSuperQuery,
JImportModal,
},
data() {
return {
code: '',
description: '线',
currentTableName:"",
url: {
getQueryInfo:'/online/cgform/api/getQueryInfo/',
getColumns: '/online/cgform/api/getColumns/',
getData: '/online/cgform/api/getData/',
optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton',
},
flowCodePre:"onl_",
isorter:{
column: 'createTime',
order: 'desc',
},
//dictOptions:{fieldName:[]}
dictOptions:{
},
cgButtonLinkList:[],
cgButtonList:[],
queryInfo:[],
// 查询参数,多个页面的查询参数用 code 作为键来区分
queryParamsMap: {},
toggleSearchStatus:false,
table: {
loading: true,
scroll:{x:false},
// 表头
columns: [],
//数据集
dataSource: [],
// 选择器
selectedRowKeys: [],
selectionRows: [],
// 分页参数
pagination: {
}
},
metaPagination:{
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' ' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
actionColumn:{
title: '',
dataIndex: 'action',
scopedSlots: { customRender: 'action' },
fixed:"right",
align:"center",
width:150
},
formTemplate:"99",
EnhanceJS:'',
hideColumns:[],
buttonSwitch:{
add:true,
update:true,
delete:true,
batch_delete:true,
import:true,
export:true,
detail:true
},
hasBpmStatus:false,
checkboxFlag:false,
// 高级查询
superQuery: {
// 字段列表
fieldList: [],
// 查询参数
params: '',
// 查询条件拼接方式 'and' or 'or'
matchType: 'and'
}
}
},
created() {
this.initAutoList();
},
mounted(){
this.cgButtonJsHandler('mounted')
},
watch: {
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initAutoList()
}
},
computed:{
rowSelectionConfig:function() {
if(!this.checkboxFlag){
return null
}
return {
fixed:true,
selectedRowKeys:this.table.selectedRowKeys,
onChange: this.handleChangeInTableSelect
}
},
queryParam: {
get() {
return this.queryParamsMap[this.code]
},
set(newVal) {
this.$set(this.queryParamsMap, this.code, newVal)
}
}
},
methods: {
hasBpmStatusFilter(){
var columnObjs = this.table.columns;
let columns = [];
for (var item of columnObjs) {
columns.push(item.dataIndex);
}
if(columns.includes('bpm_status')||columns.includes('BPM_STATUS')){
this.hasBpmStatus = true;
}else{
this.hasBpmStatus = false;
}
},
initQueryInfo(){
getAction(`${this.url.getQueryInfo}${this.code}`).then((res)=>{
console.log("--onlineList-获取查询条件配置",res);
if(res.success){
this.queryInfo = res.result
}else{
this.$message.warning(res.message)
}
})
},
initAutoList(){
if(!this.$route.params.code){
return false
}
// 清空高级查询条件
this.superQuery.params = ''
if (this.$refs.superQuery) {
this.$refs.superQuery.handleReset()
}
this.table.loading = true
this.code = this.$route.params.code
if (!this.queryParam) {
this.queryParam = {}
}
getAction(`${this.url.getColumns}${this.code}`).then((res)=>{
console.log("--onlineList-加载动态列>>",res);
if(res.success){
if(res.result.checkboxFlag == 'Y'){
this.checkboxFlag = true
}else{
this.checkboxFlag = false
}
if(res.result.paginationFlag=='Y'){
this.table.pagination = {...this.metaPagination}
}else{
this.table.pagination = false
}
this.fieldHrefSlots = res.result.fieldHrefSlots
this.dictOptions = res.result.dictOptions
this.formTemplate = res.result.formTemplate
this.description = res.result.description
this.currentTableName = res.result.currentTableName
this.initCgButtonList(res.result.cgButtonList)
this.initCgEnhanceJs(res.result.enhanceJs)
this.initButtonSwitch(res.result.hideColumns)
let currColumns = res.result.columns
for(let a=0;a<currColumns.length;a++){
if(currColumns[a].customRender){
let dictCode = currColumns[a].customRender;
let replaceFlag = '_replace_text_';
if(dictCode.startsWith(replaceFlag)){
let textFieldName = dictCode.replace(replaceFlag,'')
currColumns[a].customRender=(text,record)=>{
return record[textFieldName]
}
}else{
currColumns[a].customRender=(text)=>{
return filterMultiDictText(this.dictOptions[dictCode], text);
}
}
}
}
if(res.result.scrollFlag==1){
this.table.scroll = { x :'115%' }
}else{
this.table.scroll = { x :false }
}
currColumns.push(this.actionColumn);
this.table.columns = [...currColumns]
this.hasBpmStatusFilter();
this.loadData();
this.initQueryInfo();
//加载新路由清空checkbox选中
this.table.selectedRowKeys = [];
}else{
this.$message.warning(res.message)
}
})
},
loadData(arg){
if(this.table.pagination){
if(arg==1){
this.table.pagination.current=1
}
this.table.loading = true
let params = this.getQueryParams();//查询条件
console.log("--onlineList-查询条件-->",params)
getAction(`${this.url.getData}${this.code}`,params).then((res)=>{
console.log("--onlineList-列表数据",res)
if(res.success){
let result = res.result;
if(Number(result.total)>0){
this.table.pagination.total = Number(result.total)
this.table.dataSource = result.records
}else{
this.table.pagination.total=0;
this.table.dataSource=[]
//this.$message.warning("查无数据")
}
}else{
this.$message.warning(res.message)
}
}).finally(() => {
this.table.loading = false
})
}else{
this.loadDataNoPage()
}
},
loadDataNoPage(){
this.table.loading = true
let param = this.getQueryParams()//查询条件
param['pageSize'] = -521;
getAction(`${this.url.getData}${this.code}`,filterObj(param)).then((res)=>{
console.log("--onlineList-列表数据",res)
if(res.success){
let result = res.result;
if(Number(result.total)>0){
this.table.dataSource = result.records
}else{
this.table.dataSource=[]
}
}else{
this.$message.warning(res.message)
}
}).finally(() => {
this.table.loading = false
})
},
getQueryParams() {
let param = Object.assign({}, this.queryParam,this.isorter);
param.pageNo = this.table.pagination.current;
param.pageSize = this.table.pagination.pageSize;
param.superQueryMatchType = this.superQuery.matchType
param.superQueryParams = encodeURIComponent(this.superQuery.params)
return filterObj(param);
},
handleChangeInTableSelect(selectedRowKeys, selectionRows) {
this.table.selectedRowKeys = selectedRowKeys
this.table.selectionRows = selectionRows
this.selectedRowKeys = selectedRowKeys
},
handleTableChange(pagination, filters, sorter){
//TODO 筛选
if (Object.keys(sorter).length>0){
this.isorter.column = sorter.field;
this.isorter.order = "ascend"==sorter.order?"asc":"desc"
}
this.table.pagination = pagination;
this.loadData();
},
handleAdd(){
this.cgButtonJsHandler('beforeAdd')
this.$refs.modal.add(this.formTemplate);
},
handleImportXls(){
this.$refs.importModal.show()
},
importOk(){
this.loadData(1)
},
handleExportXls2(){
let param = this.queryParam;
if(this.table.selectedRowKeys && this.table.selectedRowKeys.length>0){
param['selections'] = this.table.selectedRowKeys.join(",")
}
let paramsStr = encodeURI(JSON.stringify(param));
console.log('paramsStr: ' + paramsStr)
let url = window._CONFIG['domianURL']+this.url.exportXls+this.code+"?paramsStr="+paramsStr
window.location.href = url;
},
handleExportXls(){
let param = this.queryParam;
if(this.table.selectedRowKeys && this.table.selectedRowKeys.length>0){
param['selections'] = this.table.selectedRowKeys.join(",")
}
console.log("导出参数",param)
let paramsStr = JSON.stringify(filterObj(param));
downFile(this.url.exportXls+this.code,{paramsStr:paramsStr}).then((data)=>{
if (!data) {
this.$message.warning("文件下载失败")
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), this.description+'.xls')
}else{
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', this.description+'.xls')
document.body.appendChild(link)
link.click()
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
})
},
handleEdit(record){
this.cgButtonLinkHandler(record,"beforeEdit","js")
this.$refs.modal.edit(this.formTemplate,record.id);
},
showLinkButton(item,record){
let btn = new ButtonExpHandler(item.exp,record);
return btn.show;
},
handleDetail(record){
this.$refs.modal.detail(this.formTemplate,record.id);
},
handleDeleteOne(record){
this.cgButtonLinkHandler(record,"beforeDelete","js")
this.handleDelete(record.id)
},
handleDelete(id){
deleteAction(this.url.optPre+this.code+"/"+id).then((res)=>{
if(res.success){
this.$message.success(res.message)
this.loadData()
}else{
this.$message.warning(res.message)
}
})
},
handleFormSuccess(){
this.loadData()
},
// 查询完 schema 后,生成高级查询的字段列表
handleGetSchema(schema) {
if (schema && schema.properties) {
let setField = (array, field) => {
let type = field.type || 'string'
type = (type === 'inputNumber' ? 'number' : type)
array.push({
type: type,
value: field.key,
text: field.title,
// 额外字典参数
dictCode: field.dictCode,
dictTable: field.dictTable,
dictText: field.dictText,
options: field.enum || field.options,
order: field.order,
})
}
let fieldList = []
for (let key in schema.properties) {
if (!schema.properties.hasOwnProperty(key)) {
continue
}
let field = schema.properties[key]
// tab = 子表
if (field.view === 'tab') {
let subTable = {
type: 'sub-table',
value: field.key,
text: field.describe,
children: []
}
for (let column of field.columns) {
setField(subTable.children, column)
}
fieldList.push(subTable)
} else {
field.key = key
setField(fieldList, field)
}
}
// 冒泡排序
for (let i = 0; i < fieldList.length; i++) {
for (let j = i + 1; j < fieldList.length; j++) {
let temp1 = fieldList[i]
let temp2 = fieldList[j]
if (temp1.order > temp2.order) {
fieldList[i] = temp2
fieldList[j] = temp1
}
}
}
this.superQuery.fieldList = fieldList
}
},
onClearSelected(){
this.table.selectedRowKeys = []
this.table.selectionRows = []
},
getImgView(text){
if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
return window._CONFIG['staticDomainURL']+"/"+text
},
downloadRowFile(text){
if(!text){
this.$message.warning("未知的文件")
return;
}
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['staticDomainURL']+"/"+text);//TODO 下载的方法
},
handleDelBatch(){
if(this.table.selectedRowKeys.length<=0){
this.$message.warning('');
return false;
}else{
let ids = "";
let that = this;
that.table.selectedRowKeys.forEach(function(val) {
ids+=val+",";
});
that.$confirm({
title:"确认删除",
content:"是否删除选中数据?",
onOk: function(){
that.handleDelete(ids)
that.onClearSelected();
}
});
}
},
searchByquery(){
this.loadData(1);
},
searchReset(){
this.queryParam = {}
this.loadData(1);
},
handleToggleSearch(){
this.toggleSearchStatus = !this.toggleSearchStatus;
},
getFormatDate(text){
if(!text){
return ''
}
let a = text;
if(a.length>10){
a = a.substring(0,10);
}
return a;
},
getImportUrl(){
return '/online/cgform/api/importXls/'+this.code
},
initCgEnhanceJs(enhanceJs){
//console.log("--onlineList-js增强",enhanceJs)
if(enhanceJs){
let Obj = eval ("(" + enhanceJs + ")");
this.EnhanceJS = new Obj(getAction,postAction,deleteAction);
this.cgButtonJsHandler('created')
}else{
this.EnhanceJS = ''
}
},
initCgButtonList(btnList){
let linkArr = []
let buttonArr = []
if(btnList && btnList.length>0){
for(let i=0;i<btnList.length;i++){
let temp = btnList[i]
if(temp.buttonStyle=='button'){
buttonArr.push(temp)
}else if(temp.buttonStyle=='link'){
linkArr.push(temp)
}
}
}
this.cgButtonLinkList = [...linkArr]
this.cgButtonList=[...buttonArr]
},
cgButtonJsHandler(buttonCode){
if(this.EnhanceJS[buttonCode]){
this.EnhanceJS[buttonCode](this)
}
},
cgButtonActionHandler(buttonCode){
//处理自定义button的 需要配置该button自定义sql
if(!this.table.selectedRowKeys || this.table.selectedRowKeys.length==0){
this.$message.warning("请先选中一条记录")
return false
}
if(this.table.selectedRowKeys.length>1){
this.$message.warning("请只选中一条记录")
return false
}
let params = {
formId:this.code,
buttonCode:buttonCode,
dataId:this.table.selectedRowKeys[0]
}
console.log("自定义按钮请求后台参数:",params)
postAction(this.url.buttonAction,params).then(res=>{
if(res.success){
this.loadData()
this.$message.success("处理完成!")
}else{
this.$message.warning("处理失败!")
}
})
},
cgButtonLinkHandler(record,buttonCode,optType){
if(optType=="js"){
if(this.EnhanceJS[buttonCode]){
this.EnhanceJS[buttonCode](this,record)
}
}else if(optType=="action"){
let params = {
formId:this.code,
buttonCode:buttonCode,
dataId:record.id
}
console.log("自定义按钮link请求后台参数",params)
postAction(this.url.buttonAction,params).then(res=>{
if(res.success){
this.loadData()
this.$message.success("处理完成!")
}else{
this.$message.warning("处理失败!")
}
})
}
},
initButtonSwitch(hideColumns){
Object.keys(this.buttonSwitch).forEach(key=>{
this.buttonSwitch[key]=true
})
if(hideColumns && hideColumns.length>0){
Object.keys(this.buttonSwitch).forEach(key=>{
if(hideColumns.indexOf(key)>=0){
this.buttonSwitch[key]=false
}
})
}
},
// 高级查询
handleSuperQuery(params, matchType) {
if (!params || params.length === 0) {
this.superQuery.params = ''
} else {
this.superQuery.params = JSON.stringify(params)
}
this.superQuery.matchType = matchType
this.loadData()
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<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>

View File

@ -1,696 +0,0 @@
<template>
<a-card :bordered="false" style="height: 100%">
<!-- -->
<div class="table-operator">
<a-button v-if="buttonSwitch.add" @click="handleAdd" type="primary" icon="plus"></a-button>
<a-button v-if="buttonSwitch.import" @click="handleImportXls" type="primary" icon="upload" style="margin-left:8px"></a-button>
<a-button v-if="buttonSwitch.export" @click="handleExportXls" type="primary" icon="download" style="margin-left:8px"></a-button>
<template v-if="cgButtonList && cgButtonList.length>0" v-for="(item,index) in cgButtonList">
<a-button
v-if=" item.optType=='js' "
:key=" 'cgbtn'+index "
@click="cgButtonJsHandler(item.buttonCode)"
type="primary"
:icon="item.buttonIcon"
style="margin-left:8px">
{{ item.buttonName }}
</a-button>
<a-button
v-else-if=" item.optType=='action' "
:key=" 'cgbtn'+index "
@click="cgButtonActionHandler(item.buttonCode)"
type="primary"
:icon="item.buttonIcon"
style="margin-left:8px">
{{ item.buttonName }}
</a-button>
</template>
<a-button
v-if="buttonSwitch.batch_delete"
@click="handleDelBatch"
style="margin-left:8px"
v-show="selectedRowKeys.length > 0"
ghost
type="primary"
icon="delete"></a-button>
</div>
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
&nbsp;<a style="font-weight: 600">{{ selectedRowKeys.length }}</a>&nbsp;&nbsp;
<a style="margin-left: 24px" @click="onClearSelected"></a>
</div>
<a-table
ref="cgformTreeList"
size="middle"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="pagination"
:loading="loading"
@change="handleTableChange"
v-bind="tableProps"
@expand="handleExpand"
style="min-height: 300px"
:expandedRowKeys="expandedRowKeys">
<template slot="dateSlot" slot-scope="text">
<span>{{ getDateNoTime(text) }}</span>
</template>
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;"></span>
<img v-else :src="getImgView(text)" height="25px" alt="图片不存在" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;"></span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="downloadRowFile(text)">
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<template v-if="showOptButton('update',record)">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
</template>
<a-dropdown>
<a class="ant-dropdown-link">
<a-icon type="down" />
</a>
<a-menu slot="overlay">
<a-menu-item >
<a @click="handleDetail(record)"></a>
</a-menu-item>
<a-menu-item v-if="showOptButton('delete',record)">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a></a>
</a-popconfirm>
</a-menu-item>
<!-- -->
<template v-if="cgButtonLinkList && cgButtonLinkList.length>0" v-for="(btnItem,btnIndex) in cgButtonLinkList">
<a-menu-item :key=" 'cgbtnLink'+btnIndex ">
<a href="javascript:void(0);" @click="cgButtonLinkHandler(record,btnItem.buttonCode,btnItem.optType)">
<a-icon v-if="btnItem.buttonIcon" :type="btnItem.buttonIcon" />
{{ btnItem.buttonName }}
</a>
</a-menu-item>
</template>
</a-menu>
</a-dropdown>
</span>
</a-table>
<onl-cgform-auto-modal @success="handleFormSuccess" ref="modal" :code="code"></onl-cgform-auto-modal>
<j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal>
</div>
</a-card>
</template>
<script>
import { getAction,postAction,deleteAction,downFile } from '@/api/manage'
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import { filterObj } from '@/utils/util';
import JImportModal from '@/components/jeecg/JImportModal'
export default {
name: 'OnlCgformTreeList',
components: {
JImportModal,
},
data() {
return {
code: '87b55a515d3441b6b98e48e5b35474a6',
description: '线',
currentTableName:"",
pidField:"",
hasChildrenField:"",
textField:'',
loading: false,
// 表头
columns: [],
//数据集
dataSource: [],
// 选择器
selectedRowKeys: [],
selectionRows: [],
// 分页参数
pagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' ' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
url: {
getColumns: '/online/cgform/api/getColumns/',
getTreeData: '/online/cgform/api/getTreeData/',
optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton',
},
isorter:{
column: 'create_time',
order: 'desc',
},
dictOptions:{
},
queryParam:{
},
actionColumn:{
title: '',
dataIndex: 'action',
scopedSlots: { customRender: 'action' },
fixed:"right",
align:"center",
width:150
},
formTemplate:"99",
/*自定义按钮-link*/
cgButtonLinkList:[],
/*自定义按钮-button*/
cgButtonList:[],
/*JS增强*/
EnhanceJS:'',
/*操作按钮权限*/
buttonSwitch:{
add:true,
update:true,
delete:true,
batch_delete:true,
import:true,
export:true
},
expandedRowKeys:[],
hasBpmStatus:false,
flowCodePre:"onl_",
}
},
created() {
this.initAutoListConfig().then(()=>{
this.loadData(1)
}).catch(msg=>{
console.log(msg)
})
},
mounted(){
//this.cgButtonJsHandler('mounted')
},
watch: {
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initAutoListConfig().then(()=>{
this.loadData(1)
}).catch(msg=>{
console.log(msg)
})
}
},
computed: {
tableProps() {
let _this = this
return {
// 列表项是否可选择
// https://vue.ant.design/components/table-cn/#rowSelection
rowSelection: {
selectedRowKeys: _this.selectedRowKeys,
onChange: (selectedRowKeys) => _this.selectedRowKeys = selectedRowKeys
}
}
}
},
methods: {
resetData(){
this.description=''
this.currentTableName=''
this.pidField=''
this.hasChildrenField=''
this.textField=''
this.columns = []
this.dataSource = []
this.selectedRowKeys=[]
this.selectionRows=[]
},
initAutoListConfig() {
return new Promise((resolve, reject) => {
if (!this.$route.params.code) {
reject("列表加载需要参数CODE为空!")
} else {
this.resetData()
this.loading = true
this.code = this.$route.params.code
getAction(`${this.url.getColumns}${this.code}`)
.then(res => {
console.log("--onlineList-加载动态列>>", res);
if(res.success){
this.configInfohandler(res)
resolve();
}else{
reject("onlineList-加载表配置信息失败")
}
this.loading = false
})
.catch(err => {
reject(err)
})
}
})
},
configInfohandler(res){
this.dictOptions = res.result.dictOptions
this.formTemplate = res.result.formTemplate
this.description = res.result.description
this.currentTableName = res.result.currentTableName
this.pidField = res.result.pidField
this.hasChildrenField = res.result.hasChildrenField
this.textField = res.result.textField
//自定义按钮
this.initCgButtonList(res.result.cgButtonList)
//JS增强
this.initCgEnhanceJs(res.result.enhanceJs)
//操作按钮权限
this.initButtonSwitch(res.result.hideColumns)
let currColumns = res.result.columns
let textFieldIndex = -1
let hasBpmStatus = false
for(let a=0;a<currColumns.length;a++){
currColumns[a].align = 'left'
//找到显示列
if(this.textField==currColumns[a].dataIndex){
textFieldIndex = a
}
//数据字典翻译
if(currColumns[a].customRender){
let dictCode = currColumns[a].customRender;
currColumns[a].customRender=(text)=>{
return filterMultiDictText(this.dictOptions[dictCode], text);
}
}
//判断是否有bpm_status
if(currColumns[a].dataIndex.toLowerCase()=='bpm_status'){
hasBpmStatus = true;
}
}
this.hasBpmStatus = hasBpmStatus;
if(textFieldIndex!=-1){
let textFieldColumn = currColumns.splice(textFieldIndex,1)
currColumns.unshift(textFieldColumn[0])
}
currColumns.push(this.actionColumn);
this.columns = [...currColumns]
},
//加载根节点
loadData(arg){
if(arg==1){
this.pagination.current=1
}
this.loading = true
this.expandedRowKeys=[]
let params = this.getQueryParams();//查询条件
params[this.pidField]='0'
console.log("--onlineList-查询条件-->",params)
getAction(`${this.url.getTreeData}${this.code}`,params).then((res)=>{
console.log("--onlineList-列表数据",res)
if(res.success){
let result = res.result;
if(Number(result.total)>0){
this.pagination.total = Number(result.total)
let dataSource = res.result.records.map(item => {
// 判断是否标记了带有子级
if (item[this.hasChildrenField] === true || item[this.hasChildrenField]=='1') {
let loadChild = { id: `${item.id}_loadChild`, name: 'loading...', isLoading: true }
item.children = [loadChild]
}
return item
})
this.dataSource = dataSource
}else{
this.pagination.total=0;
this.dataSource=[]
}
}else{
this.$message.warning(res.message)
}
this.loading = false
})
},
//加载叶子节点
handleExpand(expanded, record) {
// 判断是否是展开状态
if (expanded) {
this.expandedRowKeys.push(record.id)
if (record.children.length>0 && record.children[0].isLoading === true) {
let params = this.getQueryParams();//查询条件
params[this.pidField] = record.id
getAction(`${this.url.getTreeData}${this.code}`,params).then((res)=>{
if(res.success){
if(Number(res.result.total)>0){
let dataSource = res.result.records.map(item => {
// 判断是否标记了带有子级
if (item[this.hasChildrenField] === true || item[this.hasChildrenField]=='1') {
let loadChild = { id: `${item.id}_loadChild`, name: 'loading...', isLoading: true }
item.children = [loadChild]
}
return item
})
record.children = dataSource
}else{
record.children=''
record.hasChildrenField='0'
}
}else{
this.$message.warning(res.message)
}
})
}
}else{
let keyIndex = this.expandedRowKeys.indexOf(record.id)
if(keyIndex>=0){
this.expandedRowKeys.splice(keyIndex, 1);
}
}
},
getQueryParams() {
let param = Object.assign({}, this.queryParam,this.isorter);
param.pageNo = this.pagination.current;
param.pageSize = this.pagination.pageSize;
return filterObj(param);
},
initCgButtonList(btnList){
let linkArr = []
let buttonArr = []
if(btnList && btnList.length>0){
for(let i=0;i<btnList.length;i++){
let temp = btnList[i]
if(temp.buttonStyle=='button'){
buttonArr.push(temp)
}else if(temp.buttonStyle=='link'){
linkArr.push(temp)
}
}
}
this.cgButtonLinkList = [...linkArr]
this.cgButtonList=[...buttonArr]
},
initCgEnhanceJs(enhanceJs){
//console.log("--onlineList-js增强",enhanceJs)
if(enhanceJs){
let Obj = eval ("(" + enhanceJs + ")");
this.EnhanceJS = new Obj(getAction,postAction,deleteAction);
this.cgButtonJsHandler('created')
}else{
this.EnhanceJS = ''
}
},
initButtonSwitch(hideColumns){
if(hideColumns && hideColumns.length>0){
Object.keys(this.buttonSwitch).forEach(key=>{
if(hideColumns.indexOf(key)>=0){
this.buttonSwitch[key]=false
}
})
}
},
onClearSelected(){
this.selectedRowKeys = []
this.selectionRows = []
},
handleTableChange(pagination, filters, sorter){
//TODO 筛选
if (Object.keys(sorter).length>0){
this.isorter.column = sorter.field;
this.isorter.order = "ascend"==sorter.order?"asc":"desc"
}
this.pagination = pagination;
this.loadData();
},
/*-------数据格式化-begin----------*/
getDateNoTime(text){
if(!text){
return ''
}
let a = text;
if(a.length>10){
a = a.substring(0,10);
}
return a;
},
getImgView(text){
if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
return window._CONFIG['staticDomainURL']+"/"+text
},
downloadRowFile(text){
if(!text){
this.$message.warning("未知的文件")
return;
}
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['staticDomainURL']+"/"+text);
},
/*-------数据格式化-end----------*/
/*-------功能按钮触发事件-begin----------*/
handleEdit(record){
this.cgButtonLinkHandler(record,"beforeEdit","js")
this.$refs.modal.edit(this.formTemplate,record.id);
},
handleDetail(record){
this.$refs.modal.detail(this.formTemplate,record.id);
},
handleDeleteOne(record){
this.cgButtonLinkHandler(record,"beforeDelete","js")
this.handleDelete(record.id)
},
handleDelete(id){
deleteAction(this.url.optPre+this.code+"/"+id).then((res)=>{
if(res.success){
this.$message.success(res.message)
this.loadData()
}else{
this.$message.warning(res.message)
}
})
},
handleAdd(){
this.cgButtonJsHandler('beforeAdd')
this.$refs.modal.add(this.formTemplate);
},
handleFormSuccess(){
this.loadData()
},
handleImportXls(){
this.$refs.importModal.show()
},
importOk(){
this.loadData(1)
},
getImportUrl(){
return '/online/cgform/api/importXls/'+this.code
},
handleExportXls(){
let param = this.queryParam;
if(this.selectedRowKeys && this.selectedRowKeys.length>0){
param['selections'] = this.selectedRowKeys.join(",")
}
console.log("导出参数",param)
let paramsStr = JSON.stringify(filterObj(param));
downFile(this.url.exportXls+this.code,{paramsStr:paramsStr}).then((data)=>{
if (!data) {
this.$message.warning("文件下载失败")
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), this.description+'.xls')
}else{
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', this.description+'.xls')
document.body.appendChild(link)
link.click()
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
})
},
handleDelBatch(){
if(this.selectedRowKeys.length<=0){
this.$message.warning('');
return false;
}else{
let ids = "";
let that = this;
that.selectedRowKeys.forEach(function(val) {
ids+=val+",";
});
that.$confirm({
title:"确认删除",
content:"是否删除选中数据?",
onOk: function(){
that.handleDelete(ids)
that.onClearSelected();
}
});
}
},
/*-------功能按钮触发事件-begin----------*/
/*-------JS增强-begin----------*/
cgButtonLinkHandler(record,buttonCode,optType){
if(optType=="js"){
if(this.EnhanceJS[buttonCode]){
this.EnhanceJS[buttonCode](this,record)
}
}else if(optType=="action"){
let params = {
formId:this.code,
buttonCode:buttonCode,
dataId:record.id
}
console.log("自定义按钮link请求后台参数",params)
postAction(this.url.buttonAction,params).then(res=>{
if(res.success){
this.loadData()
this.$message.success("处理完成!")
}else{
this.$message.warning("处理失败!")
}
})
}
},
cgButtonJsHandler(buttonCode){
if(this.EnhanceJS[buttonCode]){
this.EnhanceJS[buttonCode](this)
}
},
cgButtonActionHandler(buttonCode){
//处理自定义button的 需要配置该button自定义sql
if(!this.selectedRowKeys || this.selectedRowKeys.length==0){
this.$message.warning("请先选中一条记录")
return false
}
if(this.selectedRowKeys.length>1){
this.$message.warning("请只选中一条记录")
return false
}
let params = {
formId:this.code,
buttonCode:buttonCode,
dataId:this.selectedRowKeys[0]
}
console.log("自定义按钮请求后台参数:",params)
postAction(this.url.buttonAction,params).then(res=>{
if(res.success){
this.loadData()
this.$message.success("处理完成!")
}else{
this.$message.warning("处理失败!")
}
})
},
/*-------JS增强-end----------*/
showOptButton(opt,record){
//只有当按钮属性为false,或是按钮属性为true但是流程已提交时才隐藏
if(!this.buttonSwitch[opt]){
return false
}else{
if(this.hasBpmStatus){
if(record.bpm_status !=null && record.bpm_status !='' && record.bpm_status != '1'){
return false
}
}
}
return true
},
showViewFlowButton(record){
if(this.hasBpmStatus){
if(record.bpm_status !=null && record.bpm_status !='' && record.bpm_status != '1'){
return true
}
}
return false
},
startProcess: function(record){
var that = this;
this.$confirm({
title:"提示",
content:"确认提交流程吗?",
onOk: function(){
var param = {
flowCode:that.flowCodePre+that.currentTableName,
id:record.id,
formUrl:"modules/bpm/task/form/OnlineFormDetail",
formUrlMobile:"modules/bpm/task/form/OnlineFormDetail"
}
postAction(that.url.startProcess,param).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
}else{
that.$message.warning(res.message);
}
});
}
});
},
}
}
</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>

View File

@ -1,111 +0,0 @@
<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>

View File

@ -1,269 +0,0 @@
/**
*
* @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)
}
})
})
}
/**
* SetdataSource
* @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"
}]
}

View File

@ -1,256 +0,0 @@
<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>

View File

@ -1,319 +0,0 @@
<template>
<a-card :bordered="false" style="height: 100%">
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24" v-if="queryInfo && queryInfo.length>0">
<template v-for="(item,index) in queryInfo">
<template v-if=" item.hidden==='1' ">
<a-col v-if="item.view.indexOf('Date')>=0" :md="12" :sm="16" :key=" 'query'+index " v-show="toggleSearchStatus">
<onl-cgreport-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></onl-cgreport-query-form-item>
</a-col>
<a-col v-else :md="6" :sm="8" :key=" 'query'+index " v-show="toggleSearchStatus">
<onl-cgreport-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></onl-cgreport-query-form-item>
</a-col>
</template>
<template v-else>
<a-col v-if="item.view.indexOf('Date')>=0" :md="12" :sm="16" :key=" 'query'+index ">
<onl-cgreport-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></onl-cgreport-query-form-item>
</a-col>
<a-col v-else :md="6" :sm="8" :key=" 'query'+index ">
<onl-cgreport-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></onl-cgreport-query-form-item>
</a-col>
</template>
</template>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchByQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '' : '' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<div class="table-operator" style="margin-bottom: 10px">
<a-button type="primary" icon="plus" @click="exportExcel"></a-button>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="table.columns"
:dataSource="table.dataSource"
:pagination="table.pagination"
:loading="table.loading"
:scroll="table.scroll"
:rowSelection="{fixed:true, selectedRowKeys: table.selectedRowKeys, onChange: handleChangeInTableSelect}"
@change="handleChangeInTable"
style="min-height: 300px"
>
<!-- href -->
<template
v-for="field of fieldHrefSlots"
:slot="field.slotName"
slot-scope="text, record"
>
<a @click="handleClickFieldHref(field,record)">{{ text }}</a>
</template>
</a-table>
<!-- Href -->
<a-modal v-bind="hrefComponent.model" v-on="hrefComponent.on">
<component :is="hrefComponent.is" v-bind="hrefComponent.params"/>
</a-modal>
</a-card>
</template>
<script>
import { HrefJump } from '@/mixins/OnlAutoListMixin'
import { getAction,downFile } from '@/api/manage'
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import {filterObj} from '@/utils/util';
export default {
name: 'OnlCgreportAutoList',
mixins: [HrefJump],
components: {
},
data() {
return {
// 查询参数
queryInfo: [],
// 查询参数,多个页面的查询参数用 code 作为键来区分
queryParamsMap: {},
selfParam:{
},
sorter: {
column: '',
order: 'desc',
},
dictOptions: {},
toggleSearchStatus: false, // 高级搜索 展开/关闭
reportCode: '',
description: '线',
url: {
getColumnsAndData: '/online/cgreport/api/getColumnsAndData/',
getQueryInfo: '/online/cgreport/api/getQueryInfo/',
getParamsInfo:'/online/cgreport/api/getParamsInfo/'
},
table: {
loading: true,
// 表头
columns: [],
//数据集
dataSource: [],
// 选择器
selectedRowKeys: [],
selectionRows: [],
scroll: { x: false },
// 分页参数
pagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' ' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
}
},
cgreportHeadName:""
}
},
mounted() {
this.initParamsInfo()
this.initQueryInfo();
},
watch: {
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initParamsInfo()
this.initQueryInfo();
}
},
computed: {
queryParam: {
get() {
return this.queryParamsMap[this.reportCode]
},
set(newVal) {
this.$set(this.queryParamsMap, this.reportCode, newVal)
}
}
},
methods: {
initParamsInfo(){
if(!this.$route.params.code){
return false
}
//获取报表ID
this.reportCode = this.$route.params.code;
if (!this.queryParam) {
this.queryParam = {}
}
this.selfParam={}
getAction(`${this.url.getParamsInfo}${this.reportCode}`).then((res) => {
if (res.success) {
if(res.result && res.result.length>0){
for(let i of res.result){
this.selfParam['self_'+i.paramName]=(!this.$route.query[i.paramName])?"":this.$route.query[i.paramName]
}
}
} else {
this.$message.warning(res.message)
}
this.loadData()
})
},
initQueryInfo() {
if(!this.reportCode){
return false
}
getAction(`${this.url.getQueryInfo}${this.reportCode}`).then((res) => {
console.log("获取查询条件", res);
if (res.success) {
this.queryInfo = res.result
} else {
this.$message.warning(res.message)
}
})
},
loadData(arg) {
if(!this.reportCode){
return false
}
if (arg == 1) {
this.table.pagination.current = 1
}
let params = this.getQueryParams();//查询条件
console.log(params)
//获取报表ID
console.log(' reportCode ' + this.reportCode);
this.table.loading = true
getAction(`${this.url.getColumnsAndData}${this.reportCode}`, params).then(res => {
if (res.success) {
let { data, columns, cgreportHeadName, dictOptions, fieldHrefSlots } = res.result
let columnWidth = 230
this.dictOptions = dictOptions
for(let a=0;a<columns.length;a++){
if(columns[a].customRender){
let field_name = columns[a].customRender;
columns[a].customRender = (t => t ? filterMultiDictText(this.dictOptions[field_name], t + '') : t)
}
columns.width = columnWidth
}
this.table.scroll.x = columns.length * columnWidth
this.table.columns = [...columns]
this.cgreportHeadName = cgreportHeadName
this.fieldHrefSlots = fieldHrefSlots
if (data) {
this.table.pagination.total = Number(data.total)
this.table.dataSource = data.records
} else {
this.table.pagination.total = 0
this.table.dataSource = []
}
}else{
this.$message.warn(''+res.message)
}
}).catch((e) => {
console.error(e)
this.$message.error('')
}).finally(() => {
this.table.loading = false
})
},
getQueryParams() {
let param = Object.assign({}, this.queryParam, this.sorter,this.selfParam);
param.pageNo = this.table.pagination.current;
param.pageSize = this.table.pagination.pageSize;
return filterObj(param);
},
searchByQuery() {
this.loadData(1);
},
searchReset() {
this.queryParam = {}
this.loadData(1);
},
handleToggleSearch() {
this.toggleSearchStatus = !this.toggleSearchStatus;
},
exportExcel() {
let fileName = this.cgreportHeadName
let selfParam = {}
for (let queryName in this.$route.query) {
if (this.$route.query.hasOwnProperty(queryName)) {
let value = this.$route.query[queryName]
selfParam['self_' + queryName] = value || ''
}
}
downFile(`/online/cgreport/api/exportXls/${this.reportCode}`, Object.assign(selfParam, this.queryParam)).then((data) => {
if (!data) {
this.$message.warning("文件下载失败")
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName+'.xls')
}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+'.xls')
document.body.appendChild(link)
link.click()
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
})
},
handleChangeInTableSelect(selectedRowKeys, selectionRows) {
this.table.selectedRowKeys = selectedRowKeys
this.table.selectionRows = selectionRows
},
handleChangeInTable(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
if (Object.keys(sorter).length > 0) {
this.sorter.column = sorter.field
this.sorter.order = 'ascend' == sorter.order ? 'asc' : 'desc'
} else {
this.sorter.column = null
this.sorter.order = null
}
this.table.pagination = pagination
this.loadData()
}
}
}
</script>
<style scoped>
.div {
display: flex;
align-items: center;
height: 500px
}
</style>

View File

@ -14,6 +14,12 @@
<a-input placeholder="请输入文件地址" v-model="queryParam.url"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>

View File

@ -79,26 +79,30 @@
{
title: '',
align: 'center',
dataIndex: 'dataTable'
dataIndex: 'dataTable',
width: "120"
}, {
title: 'ID',
align: 'center',
dataIndex: 'dataId'
dataIndex: 'dataId',
width: "120"
}, {
title: '',
align: 'center',
dataIndex: 'dataVersion'
dataIndex: 'dataVersion',
width: "50"
}, {
title: '',
align: 'center',
dataIndex: 'dataContent',
width: "120px",
width: "150",
scopedSlots: {customRender: 'dataContent'},
}, {
title: '',
align: 'center',
dataIndex: 'createBy'
}
dataIndex: 'createBy',
width: "100"
},
],
url: {
list: "/sys/dataLog/list",

View File

@ -5,8 +5,8 @@
<!-- -->
<a-row style="margin-left: 14px">
<a-button @click="handleAdd(2)" type="primary"></a-button>
<a-button @click="handleAdd(1)" type="primary"></a-button>
<a-button @click="handleAdd(1)" type="primary"></a-button>
<a-button @click="handleAdd(2)" type="primary"></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-button type="primary" icon="import"></a-button>
@ -73,7 +73,7 @@
<a-col :md="12" :sm="24">
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="基本信息" key="1" >
<a-card :bordered="false">
<a-card :bordered="false" v-if="selectedKeys.length>0">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
@ -146,9 +146,14 @@
</a-form>
<div class="anty-form-btn">
<a-button @click="emptyCurrForm" type="default" htmlType="button" icon="sync"></a-button>
<a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form"></a-button>
<a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form"></a-button>
</div>
</a-card>
<a-card v-else >
<a-empty>
<span slot="description"> ! </span>
</a-empty>
</a-card>
</a-tab-pane>
<a-tab-pane tab="部门权限" key="2" forceRender>
<depart-auth-modal ref="departAuth"/>
@ -224,6 +229,7 @@
visible: false,
departTree: [],
rightClickSelectedKey: '',
rightClickSelectedOrgCode: '',
hiding: true,
model: {},
dropTrigger: '',
@ -282,6 +288,8 @@
that.departTree = []
queryDepartTreeList().then((res) => {
if (res.success) {
//部门全选后,再添加部门,选中数量增多
this.allTreeKeys = [];
for (let i = 0; i < res.result.length; i++) {
let temp = res.result[i]
that.treeData.push(temp)
@ -311,6 +319,7 @@
this.dropTrigger = 'contextmenu'
console.log(node.node.eventKey)
this.rightClickSelectedKey = node.node.eventKey
this.rightClickSelectedOrgCode = node.node.dataRef.orgCode
},
onExpand(expandedKeys) {
console.log('onExpand', expandedKeys)
@ -422,8 +431,10 @@
}else{
this.orgCategoryDisabled = false;
}
this.form.getFieldDecorator('fax', {initialValue: ''})
this.form.setFieldsValue(pick(record, 'departName','orgCategory', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'))
this.$nextTick(() => {
this.form.getFieldDecorator('fax', {initialValue: ''})
this.form.setFieldsValue(pick(record, 'departName','orgCategory', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'))
})
},
getCurrSelectedTitle() {
return !this.currSelected.title ? '' : this.currSelected.title
@ -486,7 +497,7 @@
} else if (num == 2) {
let key = this.currSelected.key
if (!key) {
this.$message.warning('!')
this.$message.warning('')
return false
}
this.$refs.departModal.add(this.selectedKeys)
@ -497,12 +508,26 @@
}
},
handleDelete() {
deleteByDepartId({id: this.rightClickSelectedKey}).then((resp) => {
if (resp.success) {
this.$message.success('!')
this.loadTree()
} else {
this.$message.warning('!')
var that = this
this.$confirm({
title: '',
content: '?',
onOk: function () {
deleteByDepartId({id: that.rightClickSelectedKey}).then((resp) => {
if (resp.success) {
//删除成功后,去除已选中中的数据
that.checkedKeys.splice(that.checkedKeys.findIndex(key => key === that.rightClickSelectedKey), 1);
that.$message.success('!')
that.loadTree()
//删除后同步清空右侧基本信息内容
let orgCode=that.form.getFieldValue("orgCode");
if(orgCode && orgCode === that.rightClickSelectedOrgCode){
that.onClearSelected()
}
} else {
that.$message.warning('!')
}
})
}
})
},

View File

@ -17,6 +17,8 @@
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree"
:autoExpandParent="autoExpandParent"
:expandedKeys="iExpandedKeys"
@expand="onExpand"
/>
</template>
@ -99,7 +101,7 @@
},
methods: {
callback(key) {
console.log(key)
//console.log(key)
},
loadData() {
this.refresh();
@ -130,11 +132,15 @@
})
},
setThisExpandedKeys(node) {
//只展开一级目录
if (node.children && node.children.length > 0) {
this.iExpandedKeys.push(node.key)
//下方代码放开注释则默认展开所有节点
/**
for (let a = 0; a < node.children.length; a++) {
this.setThisExpandedKeys(node.children[a])
}
*/
}
},
refresh() {
@ -153,7 +159,7 @@
onSearch(value) {
let that = this
if (value) {
searchByKeywords({keyWord: value}).then((res) => {
searchByKeywords({keyWord: value,myDeptSearch:'1'}).then((res) => {
if (res.success) {
that.departTree = []
for (let i = 0; i < res.result.length; i++) {

View File

@ -79,6 +79,8 @@
methods: {
handleCancel(){
this.visible = false
//回收站字典列表刷新
this.$emit("refresh")
},
show(){
this.visible = true
@ -106,14 +108,25 @@
})
},
handleDelete(id){
deleteAction("/sys/dict/deletePhysic/"+id).then(res=>{
if(res.success){
this.$message.success(res.message)
this.loadData();
}else{
this.$message.warning(res.message)
}
})
this.$confirm({
title: '',
content: (<div>
<p></p>
<p style="color:red;"></p>
</div>),
centered: false,
onOk: () => {
var that = this;
deleteAction("/sys/dict/deletePhysic/"+id).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.loadData();
} else {
that.$message.warning(res.message);
}
});
},
})
}
}

View File

@ -171,6 +171,10 @@
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
if (this.superQueryParams) {
param['superQueryParams'] = encodeURI(this.superQueryParams)
param['superQueryMatchType'] = this.superQueryMatchType
}
return filterObj(param);
},

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