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

Jeecg-Boot 2.1.4 版本发布 | 重构较大,较多新功能

上级 06847cd8
Ant Design Jeecg Vue
====
当前最新版本: 2.1.3(发布日期:20191226
当前最新版本: 2.0.4(发布日期:20200224
Overview
----
基于 [Ant Design of Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/) 实现的 Ant Design Pro Vue 版
Jeecg-boot 的前端UI框架,采用前后端分离框架,提供强大代码生成器的快速开发平台。
Jeecg-boot 的前段UI框架,采用前后端分离方案,提供强大代码生成器的快速开发平台。
前端页面代码和后端功能代码一键生成,不需要写任何代码,保持jeecg一贯的强大!!
......
{
"name": "vue-antd-jeecg",
"version": "2.1.3",
"version": "2.1.4",
"private": true,
"scripts": {
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
......@@ -10,7 +10,7 @@
},
"dependencies": {
"@antv/data-set": "^0.10.2",
"@jeecg/antd-online-re": "2.1.3",
"@jeecg/antd-online-214": "^2.1.4",
"@tinymce/tinymce-vue": "^2.0.0",
"ant-design-vue": "^1.4.0",
"apexcharts": "^3.6.5",
......@@ -24,7 +24,7 @@
"lodash.pick": "^4.4.0",
"md5": "^2.2.1",
"nprogress": "^0.2.0",
"tinymce": "^5.0.2",
"tinymce": "^5.1.4",
"viser-vue": "^2.4.4",
"vue": "^2.6.10",
"vue-apexcharts": "^1.3.2",
......@@ -51,12 +51,12 @@
"babel-eslint": "^10.0.1",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0",
"html-webpack-plugin": "^4.0.0-beta.11",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"node-sass": "^4.11.0",
"sass-loader": "^7.0.1",
"vue-template-compiler": "^2.6.10",
"html-webpack-plugin": "^4.0.0-beta.11"
"vue-template-compiler": "^2.6.10"
},
"eslintConfig": {
"root": true,
......
......@@ -5,9 +5,9 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Jeecg-Boot 快速开发平台</title>
<title>Jeecg-Boot 企业级快速开发平台</title>
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="https://cdn.bootcss.com/babel-polyfill/7.6.0/polyfill.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.2.5/polyfill.js"></script>
<style>
html,
body,
......@@ -244,8 +244,8 @@
window._CONFIG = {};
window._CONFIG['domianURL'] = 'http://127.0.0.1:8080/jeecg-boot';
window._CONFIG['casPrefixUrl'] = 'http://cas.example.org:8443/cas';
window._CONFIG['imgDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/view';
window._CONFIG['downloadUrl'] = window._CONFIG['domianURL'] + '/sys/common/download';
window._CONFIG['onlinePreviewDomainURL'] = 'http://fileview.jeecg.com/onlinePreview'
window._CONFIG['staticDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/static';
window._CONFIG['pdfDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/pdf/pdfPreviewIframe';
</script>
</head>
......
......@@ -25,7 +25,7 @@ const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
//验证用户是否存在
const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params);
//改变密码
const changPassword = (params)=>putAction("/sys/user/changPassword",params);
const changePassword = (params)=>putAction("/sys/user/changePassword",params);
//权限管理
const addPermission= (params)=>postAction("/sys/permission/add",params);
......@@ -34,6 +34,7 @@ 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);
......@@ -56,6 +57,14 @@ const queryParentName = (params)=>getAction("/sys/sysDepart/queryParentName",p
const searchByKeywords = (params)=>getAction("/sys/sysDepart/searchBy",params);
const deleteByDepartId = (params)=>deleteAction("/sys/sysDepart/delete",params);
//二级部门管理
const queryDepartPermission = (params)=>getAction("/sys/permission/queryDepartPermission",params);
const saveDepartPermission = (params)=>postAction("/sys/permission/saveDepartPermission",params);
const queryTreeListForDeptRole = (params)=>getAction("/sys/sysDepartPermission/queryTreeListForDeptRole",params);
const queryDeptRolePermission = (params)=>getAction("/sys/sysDepartPermission/queryDeptRolePermission",params);
const saveDeptRolePermission = (params)=>postAction("/sys/sysDepartPermission/saveDeptRolePermission",params);
const queryMyDepartTreeList = (params)=>getAction("/sys/sysDepart/queryMyDeptTreeList",params);
//日志管理
//const getLogList = (params)=>getAction("/sys/log/list",params);
const deleteLog = (params)=>deleteAction("/sys/log/delete",params);
......@@ -94,6 +103,7 @@ 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)
export {
// imgView,
......@@ -108,7 +118,7 @@ export {
queryall,
frozenBatch,
checkOnlyUser,
changPassword,
changePassword,
getPermissionList,
addPermission,
editPermission,
......@@ -142,7 +152,15 @@ export {
queryTreeListForRole,
getSystemMenuList,
getSystemSubmenu,
loadCategoryData
getSystemSubmenuBatch,
loadCategoryData,
checkRuleByCode,
queryDepartPermission,
saveDepartPermission,
queryTreeListForDeptRole,
queryDeptRolePermission,
saveDeptRolePermission,
queryMyDepartTreeList
}
......
......@@ -112,3 +112,17 @@ export function downFile(url,parameter){
})
}
/**
* 获取文件访问路径
* @param avatar
* @param imgerver
* @param str
* @returns {*}
*/
export function getFileAccessHttpUrl(avatar,imgerver,subStr) {
if(avatar && avatar.indexOf(subStr) != -1 ){
return avatar;
}else{
return imgerver + "/" + avatar;
}
}
......@@ -5,7 +5,7 @@
}
/** Button按钮间距 */
.table-operator .ant-btn {
margin-right: 6px
margin: 8px 8px 0 0;
}
/*列表td的padding设置 可以控制列表大小*/
.ant-table-tbody .ant-table-row td {
......
<template>
<div :style="{ padding: '0 50px 32px 0' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding=" padding">
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding=" padding" :onClick="handleClick">
<v-tooltip/>
<v-legend/>
<v-axis/>
......@@ -12,9 +12,11 @@
</template>
<script>
import { ChartEventMixins } from './mixins/ChartMixins'
export default {
name: 'BarMultid',
name: 'BarAndLine',
mixins: [ChartEventMixins],
props: {
title: {
type: String,
......
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart :forceFit="true" :height="254" :data="chartData" :padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-legend />
<v-bar position="x*y" color="type" :adjust="adjust" />
<v-chart :data="data" :height="height" :force-fit="true" :onClick="handleClick">
<v-tooltip/>
<v-axis/>
<v-legend/>
<v-bar position="x*y" color="type" :adjust="adjust"/>
</v-chart>
</div>
</template>
<script>
import { DataSet } from '@antv/data-set'
import { ChartEventMixins } from './mixins/ChartMixins'
const sourceDataConst = [
{ type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 },
{ type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 },
];
const fieldsConst = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.'];
export default {
name: 'BarMultid',
mixins: [ChartEventMixins],
props: {
title: {
type: String,
default: ''
},
sourceData:{
type:Array,
default:()=>[]
dataSource: {
type: Array,
default: () => [
{ type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 },
{ type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 }
]
},
fields:{
type:Array,
default:()=>[]
fields: {
type: Array,
default: () => ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.']
},
// 别名,需要的格式:[{field:'name',alias:'姓名'}, {field:'sex',alias:'性别'}]
aliases: {
type: Array,
default: () => []
},
height: {
type: Number,
default: 254
}
},
data() {
return {
chartData:"",
height: 400,
adjust: [{
type: 'dodge',
marginRatio: 1 / 32,
}],
};
},
watch: {
'sourceData': function () {
this.drawChart();
marginRatio: 1 / 32
}]
}
},
mounted(){
this.drawChart()
},
methods:{
drawChart(){
let temp = sourceDataConst;
if(this.sourceData && this.sourceData.length>0){
temp = this.sourceData
}
const dv = new DataSet.View().source(temp);
computed: {
data() {
const dv = new DataSet.View().source(this.dataSource)
dv.transform({
type: 'fold',
fields:(!this.fields||this.fields.length==0)?fieldsConst:this.fields,
fields: this.fields,
key: 'x',
value: 'y',
});
this.chartData=dv.rows;
value: 'y'
})
// bar 使用不了 - 和 / 所以替换下
let rows = dv.rows.map(row => {
if (typeof row.x === 'string') {
row.x = row.x.replace(/[-/]/g, '_')
}
return row
})
// 替换别名
rows.forEach(row => {
for (let item of this.aliases) {
if (item.field === row.type) {
row.type = item.alias
break
}
}
})
return rows
}
}
}
......
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart :force-fit="true" :height="height" :data="data" :scale="scale">
<v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick">
<v-tooltip/>
<v-axis/>
<v-legend/>
......@@ -13,9 +13,11 @@
<script>
import { DataSet } from '@antv/data-set'
import { ChartEventMixins } from './mixins/ChartMixins'
export default {
name: 'LineChartMultid',
mixins: [ChartEventMixins],
props: {
title: {
type: String,
......
<template>
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick">
<v-tooltip :showTitle="false" dataKey="item*percent"/>
<v-axis/>
<v-legend dataKey="item"/>
......@@ -10,8 +10,11 @@
<script>
const DataSet = require('@antv/data-set')
import { ChartEventMixins } from './mixins/ChartMixins'
export default {
name: 'Pie',
mixins: [ChartEventMixins],
props: {
title: {
type: String,
......
export const ChartEventMixins = {
methods: {
handleClick(event, chart) {
this.handleEvent('click', event, chart)
},
handleEvent(eventName, event, chart) {
this.$emit(eventName, event, chart)
},
}
}
\ No newline at end of file
<template>
<a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="value" :disabled="disabled">
<a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="getValueSting" :disabled="disabled">
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
</a-radio-group>
<a-select v-else-if="tagType=='select'" :getPopupContainer = "(target) => target.parentNode" :placeholder="placeholder" :disabled="disabled" :value="value" @change="handleInput">
<a-select-option value="">请选择</a-select-option>
<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">
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
{{ item.text || item.label }}
......@@ -23,7 +23,7 @@
placeholder: String,
triggerChange: Boolean,
disabled: Boolean,
value: String,
value: [String, Number],
type: String
},
data() {
......@@ -50,6 +50,11 @@
//获取字典数据
// this.initDictData();
},
computed: {
getValueSting(){
return this.value ? this.value.toString() : null;
},
},
methods: {
initDictData() {
//根据字典Code, 初始化字典数组
......
......@@ -47,10 +47,20 @@ export function filterDictText(dictOptions, text) {
* @return String
*/
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(!text || !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++){
......
......@@ -150,7 +150,7 @@
console.log("aaaaa",res)
if(res.success){
this.checkKey = res.result.key
this.code = res.result.code
this.code = window.atob(res.result.code)
resolve();
}else{
this.$message.error("生成验证码错误,请联系系统管理员")
......
<template>
<a-upload
name="file"
listType="picture-card"
:multiple="isMultiple"
:action="uploadAction"
:headers="headers"
:data="{biz:bizPath}"
:fileList="fileList"
:beforeUpload="beforeUpload"
:disabled="disabled"
:isMultiple="isMultiple"
:showUploadList="isMultiple"
@change="handleChange"
@preview="handlePreview">
<img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="height:104px;max-width:300px"/>
<div v-else >
<a-icon :type="uploadLoading ? 'loading' : 'plus'" />
<div class="ant-upload-text">{{ text }}</div>
</div>
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()">
<img alt="example" style="width: 100%" :src="previewImage"/>
</a-modal>
</a-upload>
</template>
<script>
import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
import { getFileAccessHttpUrl } from '@/api/manage'
const uidGenerator=()=>{
return '-'+parseInt(Math.random()*10000+1,10);
}
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: 'JImageUpload',
data(){
return {
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
urlView:window._CONFIG['staticDomainURL'],
uploadLoading:false,
picUrl:false,
headers:{},
fileList: [],
previewImage:"",
previewVisible: false,
}
},
props:{
text:{
type:String,
required:false,
default:"上传"
},
/*这个属性用于控制文件上传的业务路径*/
bizPath:{
type:String,
required:false,
default:"temp"
},
value:{
type:[String,Array],
required:false
},
disabled:{
type:Boolean,
required:false,
default: false
},
isMultiple:{
type:Boolean,
required:false,
default: false
}
},
watch:{
value(val){
if (val instanceof Array) {
this.initFileList(val.join(','))
} else {
this.initFileList(val)
}
}
},
created(){
const token = Vue.ls.get(ACCESS_TOKEN);
this.headers = {"X-Access-Token":token}
},
methods:{
initFileList(paths){
if(!paths || paths.length==0){
this.fileList = [];
return;
}
this.picUrl = true;
let fileList = [];
let arr = paths.split(",")
for(var a=0;a<arr.length;a++){
let url = getFileAccessHttpUrl(arr[a],this.urlView,"http");
fileList.push({
uid: uidGenerator(),
name: getFileName(arr[a]),
status: 'done',
url: url,
response:{
status:"history",
message:arr[a]
}
})
}
this.fileList = fileList
},
beforeUpload: function(file){
var fileType = file.type;
if(fileType.indexOf('image')<0){
this.$message.warning('请上传图片');
return false;
}
},
handleChange(info) {
this.picUrl = false;
let fileList = info.fileList
if(info.file.status==='done'){
if(info.file.response.success){
this.picUrl = true;
fileList = fileList.map((file) => {
if (file.response) {
file.url = file.response.message;
}
return file;
});
}
//this.$message.success(`${info.file.name} 上传成功!`);
}else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} 上传失败.`);
}else if(info.file.status === 'removed'){
this.handleDelete(info.file)
}
this.fileList = fileList
if(info.file.status==='done' || info.file.status === 'removed'){
this.handlePathChange()
}
},
// 预览
handlePreview (file) {
this.previewImage = file.url || file.thumbUrl
this.previewVisible = true
},
getAvatarView(){
if(this.fileList.length>0){
let url = this.fileList[0].url
return getFileAccessHttpUrl(url,this.urlView,"http")
}
},
handlePathChange(){
let uploadFiles = this.fileList
let path = ''
if(!uploadFiles || uploadFiles.length==0){
path = ''
}
let arr = [];
if(!this.isMultiple){
arr.push(uploadFiles[uploadFiles.length-1].response.message)
}else{
for(var a=0;a<uploadFiles.length;a++){
arr.push(uploadFiles[a].response.message)
}
}
if(arr.length>0){
path = arr.join(",")
}
this.$emit('change', path);
},
handleDelete(file){
//如有需要新增 删除逻辑
console.log(file)
},
handleCancel() {
this.close();
this.previewVisible = false;
},
close () {
},
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
......@@ -42,6 +42,11 @@
type: String,
default: '',
required: false
},
biz:{
type: String,
default: '',
required: false
}
},
data(){
......@@ -49,7 +54,8 @@
visible:false,
uploading:false,
fileList:[],
uploadAction:''
uploadAction:'',
foreignKeys:''
}
},
watch: {
......@@ -67,10 +73,11 @@
handleClose(){
this.visible=false
},
show(){
show(arg){
this.fileList = []
this.uploading = false
this.visible = true
this.foreignKeys = arg;
},
handleRemove(file) {
const index = this.fileList.indexOf(file);
......@@ -85,6 +92,12 @@
handleImport() {
const { fileList } = this;
const formData = new FormData();
if(this.biz){
formData.append('isSingleTableImport',this.biz);
}
if(this.foreignKeys && this.foreignKeys.length>0){
formData.append('foreignKeys',this.foreignKeys);
}
fileList.forEach((file) => {
formData.append('files[]', file);
});
......
<template>
<a-modal
ref="modal"
class="j-modal-box"
:class="{'fullscreen':innerFullscreen,'no-title':isNoTitle,'no-footer':isNoFooter,}"
:visible="visible"
v-bind="_attrs"
v-on="$listeners"
@ok="handleOk"
@cancel="handleCancel"
>
<slot></slot>
<template v-if="!isNoTitle" slot="title">
<a-row class="j-modal-title-row" type="flex">
<a-col class="left">
<slot name="title">{{ title }}</slot>
</a-col>
<a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen">
<a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon"/>
</a-col>
</a-row>
</template>
<!-- 处理 scopedSlots -->
<template v-for="slotName of scopedSlotsKeys" :slot="slotName">
<slot :name="slotName"></slot>
</template>
<!-- 处理 slots -->
<template v-for="slotName of slotsKeys" v-slot:[slotName]>
<slot :name="slotName"></slot>
</template>
</a-modal>
</template>
<script>
import ACol from 'ant-design-vue/es/grid/Col'
export default {
name: 'JModal',
components: { ACol },
props: {
title: String,
// 可使用 .sync 修饰符
visible: Boolean,
// 是否在弹出时禁止 body 滚动
lockScroll: {
type: Boolean,
default: true
},
// 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符
fullscreen: {
type: Boolean,
default: true
},
// 是否允许切换全屏(允许后右上角会出现一个按钮)
switchFullscreen: {
type: Boolean,
default: false
},
},
data() {
return {
// 内部使用的 slots ,不再处理
usedSlots: ['title'],
// 缓存 body 的 overflow
bodyOverflowCache: '',
innerFullscreen: this.fullscreen,
fullscreenButtonIcon: 'fullscreen-exit',
}
},
computed: {
// 一些未处理的参数或特殊处理的参数绑定到 a-modal 上
_attrs() {
let attrs = { ...this.$attrs }
// 如果全屏就将宽度设为 100%
if (this.innerFullscreen) {
attrs['width'] = '100%'
}
return attrs
},
isNoTitle() {
return !this.title && !this.allSlotsKeys.includes('title')
},
isNoFooter() {
return this._attrs['footer'] === null
},
slotsKeys() {
return Object.keys(this.$slots).filter(key => !this.usedSlots.includes(key))
},
scopedSlotsKeys() {
return Object.keys(this.$scopedSlots).filter(key => !this.usedSlots.includes(key))
},
allSlotsKeys() {
return this.slotsKeys.concat(this.scopedSlotsKeys)
},
// 是否锁定body滚动
lockBodyScroll() {
return this.lockScroll || this.innerFullscreen
}
},
watch: {
visible() {
if (this.visible) {
this.innerFullscreen = this.fullscreen
}
if (this.lockBodyScroll) {
if (this.visible) {
this.bodyOverflowCache = document.body.style.overflow
document.body.style.overflow = 'hidden'
} else {
document.body.style.overflow = this.bodyOverflowCache
}
}
},
innerFullscreen(val) {
this.$emit('update:fullscreen', val)
},
},
methods: {
close() {
this.$emit('update:visible', false)
},
handleOk() {
this.close()
},
handleCancel() {
this.close()
},
toggleFullscreen() {
if (this.innerFullscreen) {
this.fullscreenButtonIcon = 'fullscreen'
} else {
this.fullscreenButtonIcon = 'fullscreen-exit'
}
this.innerFullscreen = !this.innerFullscreen
},
}
}
</script>
<style lang="scss">
.j-modal-box {
&.fullscreen {
top: 0;
left: 0;
padding: 0;
height: 100vh;
& .ant-modal-content {
height: 100vh;
border-radius: 0;
& .ant-modal-body {
/* title 和 footer 各占 55px */
height: calc(100% - 55px - 55px);
overflow: auto;
}
}
&.no-title, &.no-footer {
.ant-modal-body {
height: calc(100% - 55px);
}
}
&.no-title.no-footer {
.ant-modal-body {
height: 100%;
}
}
}
.j-modal-title-row {
.left {
width: calc(100% - 56px - 56px);
}
.right {
width: 56px;
.ant-modal-close {
right: 56px;
color: rgba(0, 0, 0, 0.45);
&:hover {
color: rgba(0, 0, 0, 0.75);
}
}
}
}
/deep/ {
}
}
</style>
\ No newline at end of file
<template>
<div class="j-super-query-box">
<slot>
<a-tooltip v-if="superQueryFlag" title="已有高级查询条件生效">
<a-button type="primary" @click="visible=true">
<a-icon type="appstore" theme="twoTone" :spin="true"></a-icon>
<span>高级查询</span>
</a-button>
</a-tooltip>
<a-button v-else type="primary" icon="filter" @click="visible=true">高级查询</a-button>
</slot>
<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>
<span>高级查询</span>
</a-button>
</a-tooltip>
<a-button v-else type="primary" icon="filter" @click="visible=true">高级查询</a-button>
</slot>
</div>
<a-modal
title="高级查询构造器"
......
......@@ -4,11 +4,12 @@
:multiple="true"
:action="uploadAction"
:headers="headers"
:data="{'isup':1,'bizPath':bizPath}"
:data="{'biz':bizPath}"
:fileList="fileList"
:beforeUpload="beforeUpload"
@change="handleChange"
:disabled="disabled">
:disabled="disabled"
:returnUrl="returnUrl">
<a-button>
<a-icon type="upload" />{{ text }}
</a-button>
......@@ -19,6 +20,7 @@
import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
import { getFileAccessHttpUrl } from '@/api/manage';
const FILE_TYPE_ALL = "all"
const FILE_TYPE_IMG = "image"
......@@ -38,9 +40,10 @@
data(){
return {
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
urlDownload:window._CONFIG['domianURL'] + "/sys/common/download/",
urlDownload:window._CONFIG['staticDomainURL'],
headers:{},
fileList: []
fileList: [],
newFileList: [],
}
},
props:{
......@@ -77,11 +80,25 @@
required: false,
default: false
},
/**
* update -- author:lvdandan -- date:20190219 -- for:Jupload组件增加是否返回url,
* true:仅返回url
* false:返回fileName filePath fileSize
*/
returnUrl:{
type:Boolean,
required:false,
default: true
},
},
watch:{
value(val){
if (val instanceof Array) {
this.initFileList(val.join(','))
if(this.returnUrl){
this.initFileList(val.join(','))
}else{
this.initFileListArr(val);
}
} else {
this.initFileList(val)
}
......@@ -93,6 +110,26 @@
},
methods:{
initFileListArr(val){
if(!val || val.length==0){
this.fileList = [];
return;
}
let fileList = [];
for(var a=0;a<val.length;a++){
fileList.push({
uid:uidGenerator(),
name:val[a].fileName,
status: 'done',
url: val[a].filePath,
response:{
status:"history",
message:val[a].filePath
}
})
}
this.fileList = fileList
},
initFileList(paths){
if(!paths || paths.length==0){
//return [];
......@@ -104,11 +141,12 @@
let fileList = [];
let arr = paths.split(",")
for(var a=0;a<arr.length;a++){
let url = getFileAccessHttpUrl(arr[a],this.urlDownload,"http");
fileList.push({
uid:uidGenerator(),
name:getFileName(arr[a]),
status: 'done',
url: this.urlDownload+arr[a],
url: url,
response:{
status:"history",
message:arr[a]
......@@ -156,12 +194,13 @@
if(info.file.response.success){
fileList = fileList.map((file) => {
if (file.response) {
file.url = this.urlDownload+file.response.message;
let reUrl = file.response.message;
file.url = getFileAccessHttpUrl(reUrl,this.urlDownload,"http");
}
return file;
});
}
this.$message.success(`${info.file.name} 上传成功!`);
//this.$message.success(`${info.file.name} 上传成功!`);
}else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} 上传失败.`);
}else if(info.file.status === 'removed'){
......@@ -169,7 +208,26 @@
}
this.fileList = fileList
if(info.file.status==='done' || info.file.status === 'removed'){
this.handlePathChange()
//returnUrl为true时仅返回文件路径
if(this.returnUrl){
this.handlePathChange()
}else{
//returnUrl为false时返回文件名称、文件路径及文件大小
fileList = fileList.filter((file) => {
if (file.response) {
return file.response.success === true;
}
return false;
}).map((file) => {
var fileJson = {
fileName:file.name,
filePath:file.url,
fileSize:file.size
};
this.newFileList.push(fileJson);
this.$emit('change', this.newFileList);
});
}
}
},
handleDelete(file){
......
import T from './JFormContainer.vue'
let install = function (Vue) {
Vue.component('JFormContainer',T);
}
export default { install };
\ No newline at end of file
import JModal from './JModal'
import JFormContainer from './JFormContainer.vue'
export default {
install(Vue) {
Vue.component('JFormContainer', JFormContainer)
Vue.component(JModal.name, JModal)
}
}
\ No newline at end of file
......@@ -17,9 +17,11 @@
selectable
:selectedKeys="selectedDepIds"
:checkStrictly="true"
@select="onDepSelect"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree"
:expandAction="false"
:expandedKeys.sync="expandedKeys"
@select="onDepSelect"
/>
</a-card>
</a-col>
......@@ -28,7 +30,7 @@
用户账号:
<a-input-search
:style="{width:'150px',marginBottom:'15px'}"
placeholder="请输入用户账号"
placeholder="请输入账号"
v-model="queryParam.username"
@search="onSearch"
></a-input-search>
......@@ -43,6 +45,7 @@
:dataSource="dataSource"
:pagination="ipagination"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}"
:loading="loading"
@change="handleTableChange">
</a-table>
</a-card>
......@@ -71,7 +74,7 @@
dataIndex: 'username'
},
{
title: '真实姓名',
title: '用户姓名',
align: 'center',
dataIndex: 'realname'
},
......@@ -90,14 +93,14 @@
}
},
{
title: '手机号码',
title: '手机',
align: 'center',
dataIndex: 'phone'
},
{
title: '邮箱',
title: '部门',
align: 'center',
dataIndex: 'email'
dataIndex: 'orgCode'
}
],
scrollTrigger: {},
......@@ -124,60 +127,74 @@
selectedDepIds: [],
departTree: [],
visible: false,
form: this.$form.createForm(this)
form: this.$form.createForm(this),
loading: false,
expandedKeys: [],
}
},
computed: {
// 计算属性的 getter
getType: function () {
console.log("multi: ", this.multi);
return this.multi == true ? 'checkbox' : 'radio';
}
},
watch: {
userIds() {
this.initUserNames()
}
userIds: {
immediate: true,
handler() {
this.initUserNames()
}
},
},
created() {
// 该方法触发屏幕自适应
this.resetScreenSize();
this.loadData().then((res) => {
this.initUserNames();
})
this.loadData()
},
methods: {
initUserNames() {
let names = ''
console.log("props userIds: ", this.userIds)
if (this.userIds) {
let currUserIds = this.userIds
let userIdsArr = currUserIds.split(',');
for (let item of this.dataSource) {
if (userIdsArr.includes(item.username)) {
names += "," + item.realname
// 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
let values = this.userIds.split(',') + ','
getUserList({
username: values,
pageNo: 1,
pageSize: values.length
}).then((res) => {
if (res.success) {
let selectedRowKeys = []
let realNames = []
res.result.records.forEach(user => {
realNames.push(user['realname'])
selectedRowKeys.push(user['id'])
})
this.selectedRowKeys = selectedRowKeys
this.$emit('initComp', realNames.join(','))
}
}
if (names) {
names = names.substring(1)
}
this.$emit("initComp", names)
}else{
})
} else {
// JSelectUserByDep组件bug issues/I16634
this.$emit("initComp", "")
this.$emit('initComp', '')
}
},
async loadData(arg) {
if (arg === 1) {
this.ipagination.current = 1;
}
let params = this.getQueryParams();//查询条件
await getUserList(params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
})
if (this.selectedDepIds && this.selectedDepIds.length > 0) {
await this.initQueryUserByDepId(this.selectedDepIds)
} else {
this.loading = true
let params = this.getQueryParams()//查询条件
await getUserList(params).then((res) => {
if (res.success) {
this.dataSource = res.result.records
this.ipagination.total = res.result.total
}
}).finally(() => {
this.loading = false
})
}
},
// 触发屏幕自适应
resetScreenSize() {
......@@ -191,6 +208,7 @@
showModal() {
this.visible = true;
this.queryDepartTree();
this.initUserNames()
this.loadData();
this.form.resetFields();
},
......@@ -234,7 +252,6 @@
handleSubmit() {
let that = this;
this.getSelectUserRows();
console.log(that.selectUserRows)
that.$emit('ok', that.selectUserRows, that.selectUserIds);
that.searchReset(0)
that.close();
......@@ -270,17 +287,22 @@
},
// 根据选择的id来查询用户信息
initQueryUserByDepId(selectedDepIds) {
queryUserByDepId({id: selectedDepIds.toString()}).then((res) => {
this.loading = true
return queryUserByDepId({id: selectedDepIds.toString()}).then((res) => {
if (res.success) {
this.dataSource = res.result;
this.ipagination.total = res.result.length;
}
}).finally(() => {
this.loading = false
})
},
queryDepartTree() {
queryDepartTreeList().then((res) => {
if (res.success) {
this.departTree = res.result;
// 默认展开父节点
this.expandedKeys = this.departTree.map(item => item.id)
}
})
},
......
......@@ -46,7 +46,7 @@
width: 200
},
{
title: '用户真实姓名',
title: '用户姓名',
align: "center",
dataIndex: 'realname',
},
......
......@@ -5,6 +5,8 @@
</template>
<script>
import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
import PageLayout from '../page/PageLayout'
import RouteView from './RouteView'
......@@ -40,6 +42,12 @@
/*update_begin author:wuxianquan date:20190908 for:判断打开方式,新窗口打开时this.$route.meta.internalOrExternal==true */
if(this.$route.meta.internalOrExternal != undefined && this.$route.meta.internalOrExternal==true){
this.closeCurrent();
//外部url加入token
let tokenStr = "${token}";
if(url.indexOf(tokenStr)!=-1){
let token = Vue.ls.get(ACCESS_TOKEN);
this.url = url.replace(tokenStr,token);
}
window.open(this.url);
}
/*update_end author:wuxianquan date:20190908 for:判断打开方式,新窗口打开时this.$route.meta.internalOrExternal==true */
......
......@@ -80,30 +80,41 @@
},
created() {
if (this.$route.path != indexKey) {
this.pageList.push({
name: 'dashboard-analysis',
path: indexKey,
fullPath: indexKey,
meta: {
icon: 'dashboard',
title: '首页'
}
})
this.linkList.push(indexKey)
this.addIndexToFirst()
}
// update-begin-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
let storeKey = 'route:title:' + this.$route.fullPath
let routeTitle = this.$ls.get(storeKey)
if (routeTitle) {
this.$route.meta.title = routeTitle
}
// update-end-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
this.pageList.push(this.$route)
this.linkList.push(this.$route.fullPath)
this.activePage = this.$route.fullPath
},
watch: {
'$route': function(newRoute) {
//console.log("新的路由",newRoute)
this.activePage = newRoute.fullPath
if (!this.multipage) {
this.linkList = [newRoute.fullPath]
this.pageList = [Object.assign({},newRoute)]
} else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
// update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
} else if(indexKey==newRoute.fullPath) {
//首页时 判断是否缓存 没有缓存 刷新之
if (newRoute.meta.keepAlive === false) {
this.routeReload()
}
// update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
}else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
this.linkList.push(newRoute.fullPath)
this.pageList.push(Object.assign({},newRoute))
// update-begin-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍
if (newRoute.meta.keepAlive) {
this.routeReload()
}
// update-end-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍
} else if (this.linkList.indexOf(newRoute.fullPath) >= 0) {
let oldIndex = this.linkList.indexOf(newRoute.fullPath)
let oldPositionRoute = this.pageList[oldIndex]
......@@ -114,6 +125,7 @@
let index = this.linkList.lastIndexOf(key)
let waitRouter = this.pageList[index]
this.$router.push(Object.assign({},waitRouter));
this.changeTitle(waitRouter.meta.title)
},
'multipage': function(newVal) {
if(this.reloadFlag){
......@@ -122,9 +134,44 @@
this.pageList = [this.$route]
}
}
}
},
// update-begin-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
device() {
if (this.multipage && this.linkList.indexOf(indexKey) === -1) {
this.addIndexToFirst()
}
},
// update-end-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
},
methods: {
// update-begin-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
// 将首页添加到第一位
addIndexToFirst() {
this.pageList.splice(0, 0, {
name: 'dashboard-analysis',
path: indexKey,
fullPath: indexKey,
meta: {
icon: 'dashboard',
title: '首页'
}
})
this.linkList.splice(0, 0, indexKey)
},
// update-end-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
// update-begin-author:sunjianlei date:20200120 for: 动态更改页面标题
changeTitle(title) {
let projectTitle = "Jeecg-Boot 企业级快速开发平台"
// 首页特殊处理
if (this.$route.path === indexKey) {
document.title = projectTitle
} else {
document.title = title + ' · ' + projectTitle
}
},
// update-end-author:sunjianlei date:20200120 for: 动态更改页面标题
changePage(key) {
this.activePage = key
},
......@@ -236,6 +283,9 @@
let currRouter = this.pageList[keyIndex]
let meta = Object.assign({},currRouter.meta,{title:title})
this.pageList.splice(keyIndex, 1, Object.assign({},currRouter,{meta:meta}))
if (key === this.activePage) {
this.changeTitle(title)
}
}
},
//update-end-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
......
......@@ -17,12 +17,12 @@
<div class="footer">
<div class="links">
<a href="http://jeecg-boot.mydoc.io" target="_blank">帮助</a>
<a href="http://doc.jeecg.com" target="_blank">帮助</a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank">隐私</a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank">条款</a>
<a href="https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE" target="_blank">条款</a>
</div>
<div class="copyright">
Copyright &copy; 2019 <a href="http://www.jeecg.org" target="_blank">JEECG开源社区</a> 出品
Copyright &copy; 2019 <a href="http://www.jeecg.com" target="_blank">JEECG开源社区</a> 出品
</div>
</div>
</div>
......
<template>
<div class="footer">
<div class="links">
<a href="http://www.jeecg.org" target="_blank">JEECG 首页</a>
<a href="http://www.jeecg.com" target="_blank">JEECG 首页</a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank">
<a-icon type="github"/>
</a>
......
......@@ -197,7 +197,7 @@
&.dark {
color: #000000;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
background-color: @primary-color;
background-color: white !important;
}
}
......
......@@ -154,6 +154,10 @@
//此处触发动态路由被点击事件
this.findMenuBykey(this.menus,value.key)
this.$emit("dynamicRouterShow",value.key,this.activeMenu.meta.title)
// update-begin-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
let storeKey = 'route:title:' + this.activeMenu.path
this.$ls.set(storeKey, this.activeMenu.meta.title)
// update-end-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
},
findMenuBykey(menus,key){
for(let i of menus){
......@@ -337,6 +341,10 @@
font-size: 16px;
padding: 4px;
}
.anticon {
color: white;
}
}
}
......@@ -349,6 +357,10 @@
&:hover {
background: rgba(0, 0, 0, 0.05);
}
.anticon {
color: black;
}
}
}
}
......
<template>
<component
:is="comp"
:formData="formData"
ref="compModel"
v-if="comp">
</component>
</template>
<script>
export default {
name: 'DynamicNotice',
data () {
return {
compName: this.path
}
},
computed: {
comp: function () {
if(!this.path){
return null;
}
return () => import(`@/views/${this.path}.vue`)
}
},
props: ['path','formData'],
methods: {
detail () {
setTimeout(() => {
if(this.path){
this.$refs.compModel.view(this.formData);
}
}, 200)
},
}
}
</script>
\ No newline at end of file
......@@ -72,6 +72,7 @@
</a-badge>
</span>
<show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement>
<dynamic-notice ref="showDynamNotice" :path="openPath" :formData="formData"/>
</a-popover>
</template>
......@@ -79,11 +80,13 @@
import { getAction,putAction } from '@/api/manage'
import ShowAnnouncement from './ShowAnnouncement'
import store from '@/store/'
import DynamicNotice from './DynamicNotice'
export default {
name: "HeaderNotice",
components: {
DynamicNotice,
ShowAnnouncement,
},
data () {
......@@ -105,6 +108,8 @@
websock: null,
lockReconnect:false,
heartCheck:null,
formData:{},
openPath:''
}
},
computed:{
......@@ -172,7 +177,13 @@
}
});
this.hovered = false;
this.$refs.ShowAnnouncement.detail(record);
if(record.openType==='component'){
this.openPath = record.openPage;
this.formData = {id:record.busId};
this.$refs.showDynamNotice.detail(record.openPage);
}else{
this.$refs.ShowAnnouncement.detail(record);
}
},
toMyAnnouncement(){
......
......@@ -5,11 +5,14 @@
:visible="visible"
:bodyStyle ="bodyStyle"
@cancel="handleCancel"
destroyOnClose
:footer="null">
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>
</template>
<a-card class="daily-article" :loading="loading">
<a-card-meta
:title="record.titile"
......@@ -74,7 +77,14 @@
this.modelStyle.style.top = '50px'
}
this.modelStyle.fullScreen = mode
}
},
toHandle(){
if(this.record.openType==='url'&&this.record.readFlag!== '1'){
this.visible = false;
//链接跳转
this.$router.push({path: this.record.openPage})
}
},
}
}
</script>
......
......@@ -5,7 +5,8 @@
<span class="action" @click="showClick">
<a-icon type="search"></a-icon>
</span>
<span v-show="shows" class="borders">
<!-- update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 -->
<component :is="searchMenuComp" v-show="searchMenuVisible || isMobile()" class="borders" :visible="searchMenuVisible" title="搜索菜单" :footer="null" @cancel="searchMenuVisible=false">
<a-select
class="search-input"
showSearch
......@@ -13,16 +14,20 @@
placeholder="搜索菜单"
optionFilterProp="children"
:filterOption="filterOption"
:open="isMobile()?true:null"
:getPopupContainer="(node) => node.parentNode"
:style="isMobile()?{width: '100%',marginBottom:'50px'}:{}"
@change="searchMethods"
@blur="hiddenClick"
>
<a-select-option v-for="site in search " :value="site.id">{{site.meta.title}}</a-select-option>
<a-select-option v-for="site in searchMenuOptions" :value="site.id">{{site.meta.title}}</a-select-option>
</a-select>
</span>
<!-- update-end author:sunjianlei date:20191@20 for: 解决全局样式冲突的问题 -->
</component>
<!-- update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 -->
<!-- update-end author:sunjianlei date:20191220 for: 解决全局样式冲突的问题 -->
<!-- update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
<span class="action">
<a class="logout_title" target="_blank" href="http://jeecg-boot.mydoc.io">
<a class="logout_title" target="_blank" href="http://doc.jeecg.com">
<a-icon type="question-circle-o"></a-icon>
</a>
</span>
......@@ -95,9 +100,11 @@
mixins: [mixinDevice],
data(){
return{
//菜单搜索
search:[],
shows:false
// update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
searchMenuOptions:[],
searchMenuComp: 'span',
searchMenuVisible: false,
// update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
}
},
components: {
......@@ -116,10 +123,8 @@
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
created() {
let lists = []
console.log("permissionMenuList: ",this.permissionMenuList)
this.searchMenus(lists,this.permissionMenuList)
this.search=[...lists]
console.log(this.search)
this.searchMenuOptions=[...lists]
},
computed: {
...mapState({
......@@ -129,10 +134,21 @@
})
},
/* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
watch: {
// update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
device: {
immediate: true,
handler() {
this.searchMenuVisible = false
this.searchMenuComp = this.isMobile() ? 'a-modal' : 'span'
},
},
// update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
},
methods: {
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
showClick(){
this.shows = !this.shows
showClick() {
this.searchMenuVisible = true
},
hiddenClick(){
this.shows = false
......@@ -141,8 +157,8 @@
...mapActions(["Logout"]),
...mapGetters(["nickname", "avatar","userInfo"]),
getAvatar(){
console.log('url = '+ window._CONFIG['imgDomainURL']+"/"+this.avatar())
return window._CONFIG['imgDomainURL']+"/"+this.avatar()
console.log('url = '+ window._CONFIG['staticDomainURL']+"/"+this.avatar())
return window._CONFIG['staticDomainURL']+"/"+this.avatar()
},
handleLogout() {
const that = this
......@@ -189,10 +205,17 @@
filterOption(input, option) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
searchMethods(value){
let jump = this.search.filter(item=>item.id==value)
this.$router.push({ path:jump[0].path})
// update_begin author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
searchMethods(value) {
let route = this.searchMenuOptions.filter(item => item.id === value)[0]
if (route.meta.internalOrExternal === true || route.component.includes('layouts/IframePageView')) {
window.open(route.meta.url, '_blank')
} else {
this.$router.push({ path: route.path })
}
this.searchMenuVisible = false
}
// update_end author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
/*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
}
}
......@@ -203,7 +226,7 @@
/* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
.user-wrapper .search-input {
width: 180px;
color: white;
color: inherit;
/deep/ {
.ant-select-selection {
......
......@@ -18,8 +18,8 @@ import VueApexCharts from 'vue-apexcharts'
import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
import "@jeecg/antd-online-re"
import '@jeecg/antd-online-re/dist/OnlineForm.css'
import "@jeecg/antd-online-214"
import '@jeecg/antd-online-214/dist/OnlineForm.css'
import {
ACCESS_TOKEN,
......
......@@ -236,9 +236,9 @@ export const JeecgListMixin = {
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName+'.xls')
window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls')
}else{
let url = window.URL.createObjectURL(new Blob([data]))
let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'}))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
......@@ -286,7 +286,7 @@ export const JeecgListMixin = {
if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
return window._CONFIG['imgDomainURL']+"/"+text
return window._CONFIG['staticDomainURL']+"/"+text
},
/* 文件下载 */
uploadFile(text){
......@@ -297,7 +297,7 @@ export const JeecgListMixin = {
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['domianURL'] + "/sys/common/download/"+text);
window.open(window._CONFIG['staticDomainURL']+ "/"+text);
},
}
......
export const HrefJump = {
data() {
return {
fieldHrefSlots: [],
hrefComponent: {
model: {
title: '',
width: '100%',
visible: false,
destroyOnClose: true,
style: {
top: 0,
left: 0,
height: '100%',
margin: 0,
padding: 0
},
bodyStyle: { padding: '8px', height: 'calc(100vh - 108px)', overflow: 'auto', overflowX: 'hidden' },
// 隐藏掉取消按钮
cancelButtonProps: { style: { display: 'none' } },
afterClose: () => {
// 恢复body的滚动
document.body.style.overflow = null
}
},
on: {
ok: () => this.hrefComponent.model.visible = false,
cancel: () => this.hrefComponent.model.visible = false
},
is: null,
params: {},
}
}
},
methods: {
//支持链接href跳转
handleClickFieldHref(field, record) {
let href = field.href
let urlPattern = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?/
let compPattern = /\.vue(\?.*)?$/
if (typeof href === 'string') {
href = href.trim().replace(/\${([^}]+)?}/g, (s1, s2) => record[s2])
if (urlPattern.test(href)) {
window.open(href, '_blank')
} else if (compPattern.test(href)) {
this.openHrefCompModal(href)
} else {
this.$router.push(href)
}
}
},
openHrefCompModal(href) {
// 解析 href 参数
let index = href.indexOf('?')
let path = href
if (index !== -1) {
path = href.substring(0, index)
let paramString = href.substring(index + 1, href.length)
let paramArray = paramString.split('&')
let params = {}
paramArray.forEach(paramObject => {
let paramItem = paramObject.split('=')
params[paramItem[0]] = paramItem[1]
})
this.hrefComponent.params = params
} else {
this.hrefComponent.params = {}
}
this.hrefComponent.model.visible = true
this.hrefComponent.model.title = '@/views/' + path
this.hrefComponent.is = () => import('@/views/' + (path.startsWith('/')?path.slice(1):path))
// 禁止body滚动,防止滚动穿透
setTimeout(() => {
document.body.style.overflow = 'hidden'
}, 300)
},
}
}
\ No newline at end of file
......@@ -120,6 +120,19 @@ const user = {
sessionStorage.setItem(USER_AUTH,JSON.stringify(authData));
sessionStorage.setItem(SYS_BUTTON_AUTH,JSON.stringify(allAuthData));
if (menuData && menuData.length > 0) {
//update--begin--autor:qinfeng-----date:20200109------for:JEECG-63 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示------
menuData.forEach((item, index) => {
if (item["children"]) {
let hasChildrenMenu = item["children"].filter((i) => {
return !i.hidden || i.hidden == false
})
if (hasChildrenMenu == null || hasChildrenMenu.length == 0) {
item["hidden"] = true
}
}
})
console.log(" menu show json ", menuData)
//update--end--autor:qinfeng-----date:20200109------for:JEECG-63 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示------
commit('SET_PERMISSIONLIST', menuData)
} else {
reject('getPermissionList: permissions must be a non-null array !')
......
import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
export function disabledAuthFilter(code,formData) {
......@@ -10,27 +9,30 @@ export function disabledAuthFilter(code,formData) {
}
function nodeDisabledAuth(code,formData){
console.log("页面权限禁用--NODE--开始");
var permissionList = [];
let permissionList = [];
try {
var obj = formData;
//console.log("页面权限禁用--NODE--开始",obj);
if (obj) {
let bpmList = obj.permissionList;
for (var bpm of bpmList) {
if(bpm.type == '2') {
permissionList.push(bpm);
}
}
if (formData) {
let bpmList = formData.permissionList;
permissionList = bpmList.filter(item=>item.type=='2')
// for (let bpm of bpmList) {
// if(bpm.type == '2') {
// permissionList.push(bpm);
// }
// }
}else{
return false;
}
} catch (e) {
//console.log("页面权限异常----", e);
}
if (permissionList === null || permissionList === "" || permissionList === undefined||permissionList.length<=0) {
if (permissionList.length == 0) {
return false;
}
console.log("流程节点页面权限禁用--NODE--开始");
let permissions = [];
for (var item of permissionList) {
for (let item of permissionList) {
if(item.type == '2') {
permissions.push(item.action);
}
......@@ -39,9 +41,9 @@ function nodeDisabledAuth(code,formData){
if (!permissions.includes(code)) {
return false;
}else{
for (var item2 of permissionList) {
for (let item2 of permissionList) {
if(code === item2.action){
console.log("页面权限禁用--NODE--生效");
console.log("流程节点页面权限禁用--NODE--生效");
return true;
}
}
......@@ -50,21 +52,21 @@ function nodeDisabledAuth(code,formData){
}
function globalDisabledAuth(code){
console.log("页面禁用权限--Global--开始");
//console.log("全局页面禁用权限--Global--开始");
var permissionList = [];
var allPermissionList = [];
//let authList = Vue.ls.get(USER_AUTH);
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
for (var auth of authList) {
for (let auth of authList) {
if(auth.type == '2') {
permissionList.push(auth);
}
}
//console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH));
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
for (var gauth of allAuthList) {
for (let gauth of allAuthList) {
if(gauth.type == '2') {
allPermissionList.push(gauth);
}
......@@ -73,7 +75,7 @@ function globalDisabledAuth(code){
var gFlag = false;//禁用命中
var invalidFlag = false;//无效命中
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
for (var itemG of allPermissionList) {
for (let itemG of allPermissionList) {
if(code === itemG.action){
if(itemG.status == '0'){
invalidFlag = true;
......@@ -92,7 +94,7 @@ function globalDisabledAuth(code){
return gFlag;
}
let permissions = [];
for (var item of permissionList) {
for (let item of permissionList) {
if(item.type == '2') {
permissions.push(item.action);
}
......@@ -101,9 +103,9 @@ function globalDisabledAuth(code){
if (!permissions.includes(code)) {
return gFlag;
}else{
for (var item2 of permissionList) {
for (let item2 of permissionList) {
if(code === item2.action){
console.log("页面权限解除禁用--Global--生效");
console.log("全局页面权限解除禁用--Global--生效");
gFlag = false;
}
}
......@@ -134,12 +136,12 @@ function hasColoum(item,authList){
//权限无效时不做控制,有效时控制,只能控制 显示不显示
//根据授权码前缀获取未授权的列信息
function getNoAuthCols(pre){
var permissionList = [];
var allPermissionList = [];
let permissionList = [];
let allPermissionList = [];
//let authList = Vue.ls.get(USER_AUTH);
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
for (var auth of authList) {
for (let auth of authList) {
//显示策略,有效状态
if(auth.type == '1'&&startWith(auth.action,pre)) {
permissionList.push(substrPre(auth.action,pre));
......@@ -147,7 +149,7 @@ function getNoAuthCols(pre){
}
//console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH));
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
for (var gauth of allAuthList) {
for (let gauth of allAuthList) {
//显示策略,有效状态
if(gauth.type == '1'&&gauth.status == '1'&&startWith(gauth.action,pre)) {
allPermissionList.push(substrPre(gauth.action,pre));
......
......@@ -38,7 +38,7 @@ const getUploadFileList=(paths)=>{
uid:uidGenerator(),
name:getFileName(arr[a]),
status: 'done',
url: window._CONFIG['domianURL']+"/sys/common/view/"+arr[a],
url: window._CONFIG['staticDomainURL']+"/"+arr[a],
response:{
status:"history",
message:arr[a]
......
......@@ -2,35 +2,37 @@ 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.log("页面权限控制----");
console.time()
//节点权限处理,如果命中则不进行全局权限处理
if(!filterNodePermission(el, binding, vnode)){
filterGlobalPermission(el, binding, vnode);
}
console.timeEnd() //计时结束并输出时长
}
});
}
};
/**
* 全局权限控制
* 流程节点权限控制
*/
export function filterNodePermission(el, binding, vnode) {
console.log("页面权限--NODE--");
var permissionList = [];
let permissionList = [];
try {
var obj = vnode.context.$props.formData;
let obj = vnode.context.$props.formData;
if (obj) {
let bpmList = obj.permissionList;
for (var bpm of bpmList) {
for (let bpm of bpmList) {
if(bpm.type != '2') {
permissionList.push(bpm);
}
}
}else{
return false;
}
} catch (e) {
//console.log("页面权限异常----", e);
......@@ -39,8 +41,10 @@ export function filterNodePermission(el, binding, vnode) {
//el.parentNode.removeChild(el)
return false;
}
console.log("流程节点页面权限--NODE--");
let permissions = [];
for (var item of permissionList) {
for (let item of permissionList) {
if(item.type != '2') {
permissions.push(item.action);
}
......@@ -51,7 +55,7 @@ export function filterNodePermission(el, binding, vnode) {
//el.parentNode.removeChild(el)
return false;
}else{
for (var item2 of permissionList) {
for (let item2 of permissionList) {
if(binding.value === item2.action){
return true;
}
......@@ -64,29 +68,29 @@ export function filterNodePermission(el, binding, vnode) {
* 全局权限控制
*/
export function filterGlobalPermission(el, binding, vnode) {
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) || "[]");
for (var auth of authList) {
for (let auth of authList) {
if(auth.type != '2') {
permissionList.push(auth);
}
}
//console.log("页面权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH));
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
for (var gauth of allAuthList) {
for (let gauth of allAuthList) {
if(gauth.type != '2') {
allPermissionList.push(gauth);
}
}
//设置全局配置是否有命中
var invalidFlag = false;//无效命中
let invalidFlag = false;//无效命中
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
for (var itemG of allPermissionList) {
for (let itemG of allPermissionList) {
if(binding.value === itemG.action){
if(itemG.status == '0'){
invalidFlag = true;
......@@ -103,7 +107,7 @@ export function filterGlobalPermission(el, binding, vnode) {
return;
}
let permissions = [];
for (var item of permissionList) {
for (let item of permissionList) {
if(item.type != '2'){
permissions.push(item.action);
}
......
......@@ -5,9 +5,16 @@ 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 实例
const service = axios.create({
baseURL: '/jeecg-boot', // api base_url
//baseURL: '/jeecg-boot',
baseURL: baseProject, // api base_url
timeout: 9000 // 请求超时时间
})
......
......@@ -257,6 +257,62 @@ export function cssExpand(css, id) {
document.head.appendChild(style)
}
/** 用于js增强事件,运行JS代码,可以传参 */
// options 所需参数:
// 参数名 类型 说明
// vm VueComponent vue实例
// event Object event对象
// jsCode String 待执行的js代码
// errorMessage String 执行出错后的提示(控制台)
export function jsExpand(options = {}) {
// 绑定到window上的keyName
let windowKeyName = 'J_CLICK_EVENT_OPTIONS'
if (typeof window[windowKeyName] != 'object') {
window[windowKeyName] = {}
}
// 随机生成JS增强的执行id,防止冲突
let id = randomString(16, 'qwertyuioplkjhgfdsazxcvbnm'.toUpperCase())
// 封装按钮点击事件
let code = `
(function (o_${id}) {
try {
(function (globalEvent, vm) {
${options.jsCode}
})(o_${id}.event, o_${id}.vm)
} catch (e) {
o_${id}.error(e)
}
o_${id}.done()
})(window['${windowKeyName}']['EVENT_${id}'])
`
// 创建script标签
const script = document.createElement('script')
// 将需要传递的参数挂载到window对象上
window[windowKeyName]['EVENT_' + id] = {
vm: options.vm,
event: options.event,
// 当执行完成时,无论如何都会调用的回调事件
done() {
// 执行完后删除新增的 script 标签不会撤销执行结果(已产生的结果不会被撤销)
script.outerHTML = ''
delete window[windowKeyName]['EVENT_' + id]
},
// 当js运行出错的时候调用的事件
error(e) {
console.group(`${options.errorMessage || '用户自定义JS增强代码运行出错'}${new Date()})`)
console.error(e)
console.groupEnd()
}
}
// 将事件挂载到document中
script.innerHTML = code
document.body.appendChild(script)
}
/**
* 重复值验证工具方法
*
......@@ -270,12 +326,39 @@ export function cssExpand(css, id) {
* @param callback
*/
export function validateDuplicateValue(tableName, fieldName, fieldVal, dataId, callback) {
let params = { tableName, fieldName, fieldVal, dataId }
api.duplicateCheck(params).then(res => {
res['success'] ? callback() : callback(res['message'])
}).catch(err => {
callback(err.message || err)
})
if (fieldVal) {
let params = { tableName, fieldName, fieldVal, dataId }
api.duplicateCheck(params).then(res => {
res['success'] ? callback() : callback(res['message'])
}).catch(err => {
callback(err.message || err)
})
} else {
callback()
}
}
/**
* 根据编码校验规则code,校验传入的值是否合法
*
* 使用示例:
* { validator: (rule, value, callback) => validateCheckRule('common', value, callback) }
*
* @param ruleCode 编码校验规则 code
* @param value 被验证的值
* @param callback
*/
export function validateCheckRule(ruleCode, value, callback) {
if (ruleCode && value) {
value = encodeURIComponent(value)
api.checkRuleByCode({ ruleCode, value }).then(res => {
res['success'] ? callback() : callback(res['message'])
}).catch(err => {
callback(err.message || err)
})
} else {
callback()
}
}
/**
......@@ -295,4 +378,40 @@ export function pushIfNotExist(array, value, key) {
}
array.push(value)
return true
}
/**
* 可用于判断是否成功
* @type {symbol}
*/
export const succeedSymbol = Symbol()
/**
* 可用于判断是否失败
* @type {symbol}
*/
export const failedSymbol = Symbol()
/**
* 使 promise 无论如何都会 resolve,除非传入的参数不是一个Promise对象或返回Promise对象的方法
* 一般用在 Promise.all 中
*
* @param promise 可传Promise对象或返回Promise对象的方法
* @returns {Promise<any>}
*/
export function alwaysResolve(promise) {
return new Promise((resolve, reject) => {
let p = promise
if (typeof promise === 'function') {
p = promise()
}
if (p instanceof Promise) {
p.then(data => {
resolve({ type: succeedSymbol, data })
}).catch(error => {
resolve({ type: failedSymbol, error })
})
} else {
reject('alwaysResolve: 传入的参数不是一个Promise对象或返回Promise对象的方法')
}
})
}
\ No newline at end of file
......@@ -133,7 +133,7 @@
methods: {
...mapGetters(["nickname", "avatar"]),
getAvatar(){
return window._CONFIG['imgDomainURL']+"/"+this.avatar();
return window._CONFIG['staticDomainURL']+"/"+this.avatar();
},
getTeams() {
this.$http.get('/api/workplace/teams')
......
......@@ -20,14 +20,14 @@
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="访问量" :total="8846 | NumberFormat">
<chart-card :loading="loading" title="订单量" :total="8846 | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area />
</div>
<template slot="footer">访问<span> {{ '1234' | NumberFormat }}</span></template>
<template slot="footer">订单<span> {{ '1234' | NumberFormat }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
......@@ -85,7 +85,7 @@
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="访问量" key="2">
<a-tab-pane tab="销售趋势" key="2">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="销售额趋势" :dataSource="barData"/>
......@@ -101,10 +101,10 @@
<a-row>
<a-col :span="24">
<a-card :loading="loading" :bordered="false" title="最近一周访问次数统计" :style="{ marginTop: '24px' }">
<a-card :loading="loading" :bordered="false" title="最近一周访问统计" :style="{ marginTop: '24px' }">
<a-row>
<a-col :span="6">
<head-info title="今日访问IP数" :content="loginfo.todayIp"></head-info>
<head-info title="今日IP" :content="loginfo.todayIp"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
......@@ -112,7 +112,7 @@
</a-spin>
</a-col>
<a-col :span="6">
<head-info title="今日访问次数" :content="loginfo.todayVisitCount"></head-info>
<head-info title="今日访问" :content="loginfo.todayVisitCount"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
......@@ -120,7 +120,7 @@
</a-spin>
</a-col>
<a-col :span="6">
<head-info title="访问总次数" :content="loginfo.totalVisitCount"></head-info>
<head-info title="总访问量" :content="loginfo.totalVisitCount"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
......
......@@ -185,7 +185,7 @@
},
created() {
this.user = this.userInfo
this.avatar = window._CONFIG['imgDomainURL'] +"/"+ this.userInfo.avatar
this.avatar = window._CONFIG['staticDomainURL'] +"/"+ this.userInfo.avatar
console.log('this.avatar :'+ this.avatar)
getRoleList().then(res => {
......
......@@ -9,7 +9,7 @@
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="性别">
<j-dict-select-tag v-model="formData.sex" title="性别" dictCode="sex"/>
<j-dict-select-tag v-model="formData.sex" title="性别" dictCode="sex" placeholder="请选择性别"/>
<!-- <j-dict-select-tag title="性别" dictCode="sex" disabled/>-->
</a-form-item>
</a-col>
......@@ -176,34 +176,28 @@
<a-row :gutter="24">
<a-col>
<a-form-item label="最大化弹窗">
<a-button @click="()=>modal.visible=true">最大化弹窗</a-button>
<a-form-item label="JModal弹窗">
<a-button style="margin-right: 8px;" @click="()=>modal.visible=true">点击弹出JModal</a-button>
<span style="margin-right: 8px;">全屏化:<a-switch v-model="modal.fullscreen"/></span>
<span style="margin-right: 8px;">允许切换全屏:<a-switch v-model="modal.switchFullscreen"/></span>
<span>锁定Body滚动:<a-switch v-model="modal.lockScroll"/></span>
</a-form-item>
<a-modal
:visible="modal.visible"
:width="modal.width"
:style="modal.style"
@ok="()=>modal.visible=false"
@cancel="()=>modal.visible=false">
<template slot="title">
<div style="width: 100%;height:20px;padding-right:32px;">
<div style="float: left;">{{ modal.title }}</div>
<div style="float: right;">
<a-button
icon="fullscreen"
style="width:56px;height:100%;border:0"
@click="handleClickToggleFullScreen"/>
</div>
</div>
</template>
<j-modal
:visible.sync="modal.visible"
:width="1200"
:title="modal.title"
:lockScroll="modal.lockScroll"
:fullscreen.sync="modal.fullscreen"
:switchFullscreen="modal.switchFullscreen"
>
<template v-for="(i,k) of 30">
<p :key="k">这是主体内容,高度是自适应的</p>
</template>
</a-modal>
</j-modal>
</a-col>
</a-row>
......@@ -217,10 +211,10 @@
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="树字典">
<j-tree-dict parentCode="B01" />
<j-tree-dict v-model="formData.treeDict" placeholder="请选择树字典" parentCode="A01" />
</a-form-item>
</a-col>
<a-col :span="12"></a-col>
<a-col :span="12">选中的值(v-model):{{ formData.treeDict }}</a-col>
</a-row>
<a-row :gutter="24">
......@@ -262,6 +256,45 @@
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="高级查询">
<j-super-query :fieldList="superQuery.fieldList" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="高级查询(自定义按钮)">
<j-super-query :fieldList="superQuery.fieldList">
<!-- 直接在内部写一个按钮即可,点击事件自动添加 -->
<a-button type="primary" ghost icon="clock-circle">高级查询</a-button>
</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-row>
<a-row :gutter="24" style="margin-top: 65px;margin-bottom:50px;">
<a-col :span="12">
<a-form-item label="文件上传">
<j-upload v-model="fileList"></j-upload>
</a-form-item>
</a-col>
<a-col :spapn="12">
选中的值(v-model):
<j-ellipsis :value="fileList" :length="30" v-if="fileList.length>0"/>
</a-col>
</a-row>
</a-form>
</div>
......@@ -286,10 +319,15 @@
import JTreeDict from "../../components/jeecg/JTreeDict.vue";
import JCron from "@/components/jeecg/JCron.vue";
import JTreeSelect from '@/components/jeecg/JTreeSelect'
import JSuperQuery from '@/components/jeecg/JSuperQuery'
import JUpload from '@/components/jeecg/JUpload'
import JImageUpload from '@/components/jeecg/JImageUpload'
export default {
name: 'SelectDemo',
components: {
JImageUpload,
JUpload,
JTreeDict,
JDictSelectTag,
JSelectDepart,
......@@ -299,7 +337,7 @@
JCheckbox,
JCodeEditor,
JDate, JEditor, JEllipsis, JGraphicCode, JSlider, JSelectMultiple,
JCron, JTreeSelect
JCron, JTreeSelect, JSuperQuery
},
data() {
return {
......@@ -352,11 +390,20 @@ sayHi('hello, world!')`
modal: {
title: '这里是标题',
visible: false,
width: '100%',
style: { top: '20px' },
fullScreen: true
lockScroll: true,
fullscreen: true,
switchFullscreen: true,
},
cron: '',
superQuery: {
fieldList: [
{ type: 'input', value: 'name', text: '姓名', },
{ type: 'select', value: 'sex', text: '性别', dictCode: 'sex' },
{ type: 'number', value: 'age', text: '年龄', }
]
},
fileList:[],
imgList:[],
}
},
computed: {
......@@ -399,18 +446,6 @@ sayHi('hello, world!')`
handleJSliderSuccess(value) {
this.jslider.value = value
},
/** 切换全屏显示 */
handleClickToggleFullScreen() {
let mode = !this.modal.fullScreen
if (mode) {
this.modal.width = '100%'
this.modal.style.top = '20px'
} else {
this.modal.width = '1200px'
this.modal.style.top = '50px'
}
this.modal.fullScreen = mode
},
setCorn(data){
this.$nextTick(() => {
this.form.cronExpression = data;
......
......@@ -19,11 +19,13 @@
<a-cascader :options="areaOptions" @change="onChange" :showSearch="{filter}" placeholder="Please select" />
</a-form-item>
</a-col>
<a-col :md="24" :sm="24">
<a-form-item :wrapperCol="{ span: 12, offset: 5 }">
<a-button type="primary" htmlType="submit">Submit</a-button>
</a-form-item>
</a-col>
<a-form-item :wrapperCol="{ span: 12, offset: 5 }">
<a-col :md="24" :sm="24">
<a-form-item :wrapperCol="{ span: 12, offset: 5 }">
<a-button type="primary" htmlType="submit">Submit</a-button>
</a-form-item>
</a-col>
</a-form-item>
</a-form>
</a-card>
</template>
......@@ -68,4 +70,4 @@
})
}
}
</script>
</script>
\ No newline at end of file
......@@ -35,12 +35,13 @@
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="sex">
<a-select v-decorator="['sex', {}]" placeholder="请选择性别">
<a-select-option value="">请选择性别</a-select-option>
<a-select-option value="1">男性</a-select-option>
<a-select-option value="2">女性</a-select-option>
</a-select>
label="性别">
<!-- <a-select v-decorator="['sex', {}]" placeholder="请选择性别">
<a-select-option value="">请选择</a-select-option>
<a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option>
</a-select>-->
<j-dict-select-tag type="radio" v-decorator="['sex', {}]" :trigger-change="true" dictCode="sex"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
......
......@@ -2,7 +2,7 @@
<a-card :bordered="false">
<a-tabs defaultActiveKey="1" @change="callback">
<a-tab-pane tab="柱状图" key="1">
<a-row :gutter="24">
<a-row>
<a-col :span="10">
<a-radio-group :value="barType" @change="statisticst">
<a-radio-button value="year">按年统计</a-radio-button>
......
......@@ -43,24 +43,7 @@
:wrapperCol="wrapperCol"
label="身份证扫描件"
hasFeedback>
<a-upload
:action="uploadAction"
listType="picture-card"
:headers="headers"
:fileList="fileList"
@change="handleChange"
@preview="handlePreview"
>
<a-button>
<a-icon type="upload"/>
upload
</a-button>
</a-upload>
<a-modal :visible="previewVisible" :footer="null" @cancel="handlePicCancel">
<img alt="example" style="width: 100%" :src="previewImage"/>
</a-modal>
<br/>
<j-image-upload text="上传" v-model="fileList" :isMultiple="true"></j-image-upload>
</a-form-item>
<a-form-item
:labelCol="labelCol"
......@@ -88,11 +71,11 @@
import pick from 'lodash.pick'
import Vue from 'vue'
import {ACCESS_TOKEN} from "@/store/mutation-types"
import { getUploadFileList,getFilePaths } from '@/utils/commonUploadFile.js'
import JImageUpload from '../../../../components/jeecg/JImageUpload'
export default {
name: "JeecgOrderCustomerModal",
components: { JImageUpload },
data() {
return {
title: "操作",
......@@ -177,7 +160,7 @@
add: "/test/order/addCustomer",
edit: "/test/order/editCustomer",
fileUpload: window._CONFIG['domianURL'] + "/sys/common/upload",
imgerver: window._CONFIG['domianURL'] + "/sys/common/view",
imgerver: window._CONFIG['staticDomainURL'],
getOrderCustomerList: "/test/order/listOrderCustomerByMainId",
},
validatorRules: {
......@@ -222,8 +205,6 @@
this.form.resetFields();
this.orderId = record.orderId;
let currFileList = getUploadFileList(record.idcardPic)
this.fileList = [...currFileList]
this.model = Object.assign({}, record);
if (record.id) {
this.hiding = false;
......@@ -232,6 +213,9 @@
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'id', 'name', 'sex', 'idcard','telphone', 'orderId', 'createBy', 'createTime', 'updateBy', 'updateTime'))
});
setTimeout(() => {
this.fileList = record.idcardPic
}, 5)
} else {
this.addStatus = false;
this.editStatus = true;
......@@ -262,7 +246,7 @@
let formData = Object.assign(this.model, values);
console.log(formData);
formData.orderId = this.orderId;
formData.idcardPic = getFilePaths(this.fileList)
formData.idcardPic = this.fileList;
httpAction(httpurl, formData, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
......
......@@ -6,13 +6,13 @@
<a-form layout="inline">
<a-row :gutter="24">
<a-col :md="6" :sm="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 :md="6" :sm="24">
<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>
......@@ -25,10 +25,10 @@
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="doCgformButton" type="primary" icon="highlight" style="margin-left:8px">自定义按钮</a-button>
<a-button @click="doEnhanceJs" type="primary" icon="strikethrough" style="margin-left:8px">JS增强</a-button>
<a-button @click="doEnhanceSql" type="primary" icon="filter" style="margin-left:8px">SQL增强</a-button>
<a-button @click="doEnhanceJava" type="primary" icon="tool" style="margin-left:8px">Java增强</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-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
......@@ -37,7 +37,7 @@
删除
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-button> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
......@@ -348,6 +348,9 @@
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<style lang="less">
.ant-card-body .table-operator {
margin-bottom: 18px;
......
......@@ -6,18 +6,22 @@
<a-form layout="inline">
<a-row :gutter="24">
<a-col :md="6" :sm="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 :md="6" :sm="24">
<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 :md="6" :sm="24">
<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>
......@@ -31,12 +35,12 @@
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button @click="doCgformButton" type="primary" icon="highlight" style="margin-left:8px">自定义按钮</a-button>
<a-button @click="doEnhanceJs" type="primary" icon="strikethrough" style="margin-left:8px">JS增强</a-button>
<a-button @click="doEnhanceSql" type="primary" icon="filter" v-has="'online:sql'" style="margin-left:8px">SQL增强</a-button>
<a-button @click="doEnhanceJava" type="primary" icon="tool" style="margin-left:8px">Java增强</a-button>
<a-button @click="importOnlineForm" type="primary" icon="database" style="margin-left:8px">从数据库导入表单</a-button>
<a-button @click="goGenerateCode" v-has="'online:goGenerateCode'" type="primary" icon="database" style="margin-left:8px">代码生成</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">
......@@ -45,7 +49,7 @@
删除
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-button> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
......@@ -204,8 +208,12 @@
title: '表类型',
align: 'center',
dataIndex: 'tableType',
customRender: (text) => {
return filterDictText(this.tableTypeDictOptions, `${text}`)
customRender: (text, record) => {
let tbTypeText = filterDictText(this.tableTypeDictOptions, `${text}`)
if(record.isTree === 'Y'){
tbTypeText+='(树)'
}
return tbTypeText;
}
},
{
......@@ -316,10 +324,14 @@
this.syncFormId = id
},
goPageOnline(rd) {
if(rd.isTree=='Y'){
this.$router.push({ path: '/online/cgformTreeList/' + rd.id })
if(rd.themeTemplate === 'erp'){
this.$router.push({ path: '/online/cgformErpList/' + rd.id })
}else{
this.$router.push({ path: '/online/cgformList/' + rd.id })
if(rd.isTree=='Y'){
this.$router.push({ path: '/online/cgformTreeList/' + rd.id })
}else{
this.$router.push({ path: '/online/cgformList/' + rd.id })
}
}
},
handleOnlineUrlClose() {
......@@ -438,6 +450,9 @@
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<style lang="less">
.ant-card-body .table-operator {
margin-bottom: 18px;
......
......@@ -40,16 +40,15 @@
<!-- 操作按钮区域 -->
<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>
<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"
style="margin-left:8px">
:icon="item.buttonIcon">
{{ item.buttonName }}
</a-button>
<a-button
......@@ -57,8 +56,7 @@
:key=" 'cgbtn'+index "
@click="cgButtonActionHandler(item.buttonCode)"
type="primary"
:icon="item.buttonIcon"
style="margin-left:8px">
:icon="item.buttonIcon">
{{ item.buttonName }}
</a-button>
</template>
......@@ -69,13 +67,11 @@
:fieldList="superQuery.fieldList"
:saveCode="$route.fullPath"
:loading="table.loading"
style="margin-left: 8px;"
@handleSuperQuery="handleSuperQuery"/>
<a-button
v-if="buttonSwitch.batch_delete"
@click="handleDelBatch"
style="margin-left:8px"
v-show="table.selectedRowKeys.length > 0"
ghost
type="primary"
......@@ -103,6 +99,16 @@
: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>
......@@ -149,23 +155,17 @@
更多 <a-icon type="down" />
</a>
<a-menu slot="overlay">
<a-menu-item >
<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>
<a href="javascript:;" @click="startProcess(record)">提交流程</a>
</a-menu-item>
<a-menu-item v-if="buttonSwitch.delete">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</template>
<template v-else>
<a-menu-item @click="handlePreviewPic(record)">审批进度</a-menu-item>
</template>
</template>
<template v-else>
<a-menu-item v-if="buttonSwitch.delete">
......@@ -175,7 +175,7 @@
</a-menu-item>
</template>
<template v-if="cgButtonLinkList && cgButtonLinkList.length>0" v-for="(btnItem,btnIndex) in cgButtonLinkList">
<a-menu-item :key=" 'cgbtnLink'+btnIndex ">
<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 }}
......@@ -192,20 +192,27 @@
<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 { filterObj } from '@/utils/util';
import { cloneObject, filterObj } from '@/utils/util'
import JImportModal from '@/components/jeecg/JImportModal'
import JSuperQuery from '@comp/jeecg/JSuperQuery'
export default {
name: 'OnlCgFormAutoList',
mixins: [HrefJump],
components: {
JSuperQuery,
JImportModal,
......@@ -222,7 +229,6 @@
optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton',
startProcess: "/process/extActProcess/startMutilProcess",
},
flowCodePre:"onl_",
isorter:{
......@@ -282,7 +288,8 @@
delete:true,
batch_delete:true,
import:true,
export:true
export:true,
detail:true
},
hasBpmStatus:false,
checkboxFlag:false,
......@@ -304,8 +311,7 @@
this.cgButtonJsHandler('mounted')
},
watch: {
'$route.path'(newVal,oldVal) {
console.log('$route.path: ',oldVal)
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initAutoList()
}
......@@ -343,30 +349,6 @@
this.hasBpmStatus = 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);
}
});
}
});
},
initQueryInfo(){
getAction(`${this.url.getQueryInfo}${this.code}`).then((res)=>{
console.log("--onlineList-获取查询条件配置",res);
......@@ -407,6 +389,7 @@
this.table.pagination = false
}
this.fieldHrefSlots = res.result.fieldHrefSlots
this.dictOptions = res.result.dictOptions
this.formTemplate = res.result.formTemplate
this.description = res.result.description
......@@ -441,6 +424,8 @@
this.hasBpmStatusFilter();
this.loadData();
this.initQueryInfo();
//加载新路由,清空checkbox选中
this.table.selectedRowKeys = [];
}else{
this.$message.warning(res.message)
}
......@@ -569,6 +554,10 @@
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);
},
......@@ -604,7 +593,8 @@
dictCode: field.dictCode,
dictTable: field.dictTable,
dictText: field.dictText,
options: field.enum || field.options
options: field.enum || field.options,
order: field.order,
})
}
let fieldList = []
......@@ -630,6 +620,17 @@
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
}
},
......@@ -641,7 +642,7 @@
if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
return window._CONFIG['imgDomainURL']+"/"+text
return window._CONFIG['staticDomainURL']+"/"+text
},
downloadRowFile(text){
if(!text){
......@@ -651,7 +652,7 @@
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['downloadUrl']+"/"+text);//TODO 下载的方法
window.open(window._CONFIG['staticDomainURL']+"/"+text);//TODO 下载的方法
},
handleDelBatch(){
if(this.table.selectedRowKeys.length<=0){
......@@ -777,13 +778,15 @@
}
},
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
}
})
}
},
......@@ -801,6 +804,9 @@
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<style>
.ant-card-body .table-operator{
margin-bottom: 18px;
......
......@@ -98,15 +98,6 @@
<a-menu-item >
<a @click="handleDetail(record)">详情</a>
</a-menu-item>
<a-menu-item v-if="showSubmitFlowButton(record)">
<a @click="startProcess(record)">提交流程</a>
</a-menu-item>
<template v-if="showViewFlowButton(record)">
<a-menu-item @click="handlePreviewPic(record)">审批进度</a-menu-item>
</template>
<a-menu-item v-if="showOptButton('delete',record)">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a>删除</a>
......@@ -146,7 +137,7 @@
export default {
name: 'OnlCgformTreeList',
components: {
JImportModal
JImportModal,
},
data() {
return {
......@@ -183,7 +174,6 @@
optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton',
startProcess: "/process/extActProcess/startMutilProcess"
},
isorter:{
column: 'create_time',
......@@ -482,7 +472,7 @@
if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
return window._CONFIG['imgDomainURL']+"/"+text
return window._CONFIG['staticDomainURL']+"/"+text
},
downloadRowFile(text){
if(!text){
......@@ -492,7 +482,7 @@
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['downloadUrl']+"/"+text);
window.open(window._CONFIG['staticDomainURL']+"/"+text);
},
/*-------数据格式化-end----------*/
......@@ -651,14 +641,6 @@
}
return true
},
showSubmitFlowButton(record){
if(this.hasBpmStatus){
if(record.bpm_status ==null || record.bpm_status =='' || record.bpm_status == '1'){
return true
}
}
return false
},
showViewFlowButton(record){
if(this.hasBpmStatus){
if(record.bpm_status !=null && record.bpm_status !='' && record.bpm_status != '1'){
......@@ -691,6 +673,7 @@
}
});
},
}
}
</script>
......
<template>
<a-card :bordered="false" style="height: 100%">
<online-common-list
:ref="'onl_'+mainModel.currentTableName"
:code="code"
:model="mainModel"
@seleted="onSelected">
</online-common-list>
<a-tabs defaultActiveKey="0">
<a-tab-pane v-for="(item,index) in subList" :tab="item.description" :key="index+''" :forceRender="true" >
<online-common-list
:ref="item.currentTableName"
:code="item.code"
:model="item"
:main="selectedRow">
</online-common-list>
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<script>
import { getAction } from '@/api/manage'
export default {
name: 'OnlCgformErpList',
components:{
},
data(){
return {
code:'',
url: {
getColumns: '/online/cgform/api/getErpColumns/',
},
mainModel:{},
subList:[],
mainId:'',
selectedRow:{}
}
},
watch: {
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initColumnConfig()
}
},
created() {
this.initColumnConfig();
},
methods:{
getSubIndex(index){
return index+1 + ''
},
getSubRef(item){
let ref = item.currentTableName
console.log("ref string",ref)
return ref;
},
initColumnConfig(){
if(!this.$route.params.code){
return false
}
this.code = this.$route.params.code
getAction(`${this.url.getColumns}${this.code}`).then((res)=>{
console.log("erp表单配置",res)
if(res.success){
this.mainModel = res.result.main
this.subList = res.result.subList
this.$nextTick(()=>{
this.$refs['onl_'+this.mainModel.currentTableName].initListByModel();
if(this.subList && this.subList.length>0){
for(let item of this.subList){
this.$refs[item.currentTableName][0].initListByModel();
}
}
});
}
})
},
onSelected(row){
console.log("onSelected",row)
this.selectedRow = row;
}
}
}
</script>
<style>
.ant-card-body .table-operator{
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td{
padding-top:15px;
padding-bottom:15px;
}
.anty-row-operator button{margin: 0 5px}
.ant-btn-danger{background-color: #ffffff}
.anty-img-wrap{height:25px;position: relative;}
.anty-img-wrap > img{max-height:100%;}
.ant-modal-cust-warp{height: 100%}
.ant-modal-cust-warp .ant-modal-body{height:calc(100% - 110px) !important;overflow-y: auto}
.ant-modal-cust-warp .ant-modal-content{height:90% !important;overflow-y: hidden}
</style>
\ No newline at end of file
......@@ -109,6 +109,7 @@ export function getMasterTableInitialData() {
// table2
isShowForm: '0',
isShowList: '0',
isReadOnly: '1',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
......
......@@ -31,7 +31,21 @@
@change="handleChange">
<a-button>
<a-icon type="upload"/>
文件上传
OSS文件上传
</a-button>
</a-upload>
<a-upload
name="file"
:multiple="false"
:action="minioUploadAction"
:headers="tokenHeader"
:showUploadList="false"
:beforeUpload="beforeUpload"
@change="handleChange">
<a-button>
<a-icon type="upload"/>
MINIO文件上传
</a-button>
</a-upload>
</div>
......@@ -58,7 +72,9 @@
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="ossDelete(record.id)">删除</a>
<a @click="handlePreview(record)">预览</a>
<a-divider type="vertical"/>
<a @click="ossDelete(record.id)">删除</a>
</span>
</a-table>
......@@ -108,14 +124,18 @@
url: {
upload: "/oss/file/upload",
list: "/oss/file/list",
delete: "/oss/file/delete"
delete: "/oss/file/delete",
minioUpload: "/sys/upload/uploadMinio"
}
}
},
computed: {
uploadAction() {
return window._CONFIG['domianURL'] + this.url.upload;
}
},
minioUploadAction() {
return window._CONFIG['domianURL'] + this.url.minioUpload;
},
},
methods: {
beforeUpload(file) {
......@@ -139,10 +159,10 @@
this.loadData()
this.$message.success(`${info.file.name} 上传成功!`);
} else {
this.$message.error(`${info.file.name} 上传失败.`);
this.$message.error(`${info.file.response.message}`);
}
} else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} 上传失败.`);
this.$message.error(`${info.file.response.message}`);
}
},
ossDelete(id) {
......@@ -154,11 +174,17 @@
that.handleDelete(id)
}
});
},
handlePreview(record) {
if (record && record.url) {
let url = window._CONFIG['onlinePreviewDomainURL'] + '?url=' + encodeURIComponent(record.url)
window.open(url, '_blank')
}
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
@import '~@assets/less/common.less';
</style>
......@@ -17,8 +17,7 @@
<div style="background: #fff;padding-left:16px;height: 100%; margin-top: 5px">
<a-alert type="info" :showIcon="true">
<div slot="message">
当前选择:
<a v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</a>
当前选择:<span v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</span>
<a v-if="this.currSelected.title" style="margin-left: 10px" @click="onClearSelected">取消选择</a>
</div>
</a-alert>
......@@ -72,82 +71,90 @@
<!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
</a-col>
<a-col :md="12" :sm="24">
<a-card :bordered="false">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构名称">
<a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/>
</a-form-item>
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
<a-tree-select
style="width:100%"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="treeData"
:disabled="disable"
v-model="model.parentId"
placeholder="无">
</a-tree-select>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构编码">
<a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构类型">
<template v-if="orgCategoryDisabled">
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio value="1">
公司
</a-radio>
</a-radio-group>
</template>
<template v-else>
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio value="2">
部门
</a-radio>
<a-radio value="3">
岗位
</a-radio>
</a-radio-group>
</template>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="排序">
<a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="手机号">
<a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="地址">
<a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="备注">
<a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/>
</a-form-item>
</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>
</div>
</a-card>
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="基本信息" key="1" >
<a-card :bordered="false">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构名称">
<a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/>
</a-form-item>
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
<a-tree-select
style="width:100%"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="treeData"
:disabled="disable"
v-model="model.parentId"
placeholder="无">
</a-tree-select>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构编码">
<a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构类型">
<template v-if="orgCategoryDisabled">
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio value="1">
公司
</a-radio>
</a-radio-group>
</template>
<template v-else>
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio value="2">
部门
</a-radio>
<a-radio value="3">
岗位
</a-radio>
</a-radio-group>
</template>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="排序">
<a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="手机号">
<a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="地址">
<a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="备注">
<a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/>
</a-form-item>
</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>
</div>
</a-card>
</a-tab-pane>
<a-tab-pane tab="部门权限" key="2" forceRender>
<depart-auth-modal ref="departAuth"/>
</a-tab-pane>
</a-tabs>
</a-col>
<depart-modal ref="departModal" @ok="loadTree"></depart-modal>
</a-row>
......@@ -158,6 +165,7 @@
import {queryDepartTreeList, searchByKeywords, deleteByDepartId} from '@/api/api'
import {httpAction, deleteAction} from '@/api/manage'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import DepartAuthModal from './modules/DepartAuthModal'
// 表头
const columns = [
{
......@@ -201,6 +209,7 @@
name: 'DepartList',
mixins: [JeecgListMixin],
components: {
DepartAuthModal,
DepartModal
},
data() {
......@@ -403,7 +412,7 @@
this.selectedKeys = [record.key]
this.model.parentId = record.parentId
this.setValuesToForm(record)
this.$refs.departAuth.show(record.id);
},
// 触发onSelect事件时,为部门树右侧的form表单赋值
......@@ -425,6 +434,7 @@
this.currSelected = {}
this.form.resetFields()
this.selectedKeys = []
this.$refs.departAuth.departId = ''
},
handleNodeTypeChange(val) {
this.currSelected.nodeType = val
......
......@@ -6,7 +6,7 @@
<a-input-search @search="onSearch" style="width:100%;margin-top: 10px" placeholder="请输入部门名称"/>
<!-- 树-->
<template>
<template v-if="userIdentity === '2' && departTree.length>0">
<!--组织机构-->
<a-tree
......@@ -16,10 +16,14 @@
@select="onSelect"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree"
:autoExpandParent="autoExpandParent"
/>
</template>
<div style="margin-top: 24px;" v-else-if="userIdentity === '2' && departTree.length==0">
<h3><span>您的部门下暂无有效部门信息</span></h3>
</div>
<div style="margin-top: 24px;" v-else><h3>普通员工暂此权限</h3></div>
</div>
</a-card>
</a-col>
......@@ -30,7 +34,10 @@
<Dept-Base-Info ref="DeptBaseInfo"></Dept-Base-Info>
</a-tab-pane>
<a-tab-pane tab="用户信息" key="2">
<Dept-User-Info ref="DeptUserInfo"></Dept-User-Info>
<Dept-User-Info ref="DeptUserInfo" @clearSelectedDepartKeys="clearSelectedDepartKeys"></Dept-User-Info>
</a-tab-pane>
<a-tab-pane tab="部门角色" key="3" forceRender>
<dept-role-info ref="DeptRoleInfo" @clearSelectedDepartKeys="clearSelectedDepartKeys"/>
</a-tab-pane>
</a-tabs>
</a-card>
......@@ -40,13 +47,15 @@
<script>
import DeptBaseInfo from './modules/DeptBaseInfo'
import DeptUserInfo from './modules/DeptUserInfo'
import {queryDepartTreeList, searchByKeywords} from '@/api/api'
import {queryMyDepartTreeList, searchByKeywords} from '@/api/api'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import DeptRoleInfo from './modules/DeptRoleInfo'
export default {
name: 'DepartUserList',
mixins: [JeecgListMixin],
components: {
DeptRoleInfo,
DeptBaseInfo,
DeptUserInfo,
},
......@@ -85,6 +94,7 @@
nodes: [],
edges: []
},
userIdentity:"",
}
},
methods: {
......@@ -94,12 +104,19 @@
loadData() {
this.refresh();
},
clearSelectedDepartKeys() {
this.checkedKeys = [];
this.selectedKeys = [];
this.currentDeptId = '';
this.$refs.DeptUserInfo.currentDeptId='';
this.$refs.DeptRoleInfo.currentDeptId='';
},
loadTree() {
var that = this
that.treeData = []
that.departTree = []
queryDepartTreeList().then((res) => {
if (res.success) {
queryMyDepartTreeList().then((res) => {
if (res.success && res.result ) {
for (let i = 0; i < res.result.length; i++) {
let temp = res.result[i]
that.treeData.push(temp)
......@@ -109,6 +126,7 @@
}
this.loading = false
}
that.userIdentity = res.message
})
},
setThisExpandedKeys(node) {
......@@ -161,6 +179,7 @@
this.$refs.DeptBaseInfo.open(record);
this.$refs.DeptUserInfo.open(record);
this.$refs.DeptRoleInfo.open(record);
// }
// else {
// this.checkedKeys = [];
......@@ -180,6 +199,8 @@
this.$refs.DeptBaseInfo.open(record);
this.$refs.DeptUserInfo.onClearSelected();
this.$refs.DeptUserInfo.open(record);
this.$refs.DeptRoleInfo.onClearSelected();
this.$refs.DeptRoleInfo.open(record);
},
},
created() {
......
......@@ -30,6 +30,7 @@
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-button type="primary" icon="sync" @click="refleshCache()">刷新缓存</a-button>
<a-button type="primary" icon="hdd" @click="openDeleteList">回收站</a-button>
</div>
......@@ -70,6 +71,7 @@
import DictModal from './modules/DictModal'
import DictItemList from './DictItemList'
import DictDeleteList from './DictDeleteList'
import { getAction } from '@/api/manage'
export default {
name: "DictList",
......@@ -132,6 +134,7 @@
delete: "/sys/dict/delete",
exportXlsUrl: "sys/dict/exportXls",
importExcelUrl: "sys/dict/importExcel",
refleshCache: "sys/dict/refleshCache",
},
}
},
......@@ -165,9 +168,18 @@
that.queryParam.dictCode = "";
that.loadData(this.ipagination.current);
},
openDeleteList(){
this.$refs.dictDeleteList.show()
},
refleshCache(){
getAction(this.url.refleshCache).then((res) => {
if (res.success) {
this.$message.success("刷新缓存完成!");
}
}).catch(e=>{
this.$message.warn("刷新缓存失败!");
console.log("刷新失败",e)
})
}
},
watch: {
......
......@@ -29,7 +29,9 @@
:dataSource="dataSource"
:loading="loading"
@expand="expandSubmenu"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}">
:expandedRowKeys="expandedRowKeys"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@expandedRowsChange="handleExpandedRowsChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
......@@ -79,7 +81,7 @@
<script>
import PermissionModal from './modules/PermissionModal'
import { getSystemMenuList,getSystemSubmenu } from '@/api/api'
import { getSystemMenuList, getSystemSubmenu, getSystemSubmenuBatch } from '@/api/api'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import PermissionDataRuleList from './PermissionDataRuleList'
import JEllipsis from '@/components/jeecg/JEllipsis'
......@@ -140,7 +142,7 @@
]
export default {
name: 'PermissionList',
name: 'PermissionListAsync',
mixins: [JeecgListMixin],
components: {
PermissionDataRuleList,
......@@ -153,6 +155,8 @@
// 表头
columns: columns,
loading: false,
// 展开的行,受控属性
expandedRowKeys: [],
url: {
list: '/sys/permission/list',
delete: '/sys/permission/delete',
......@@ -162,23 +166,45 @@
},
methods: {
loadData() {
this.dataSource = []
this.loading = true
getSystemMenuList().then((res) => {
if (res.success) {
console.log(res.result)
this.dataSource = res.result
return this.loadDataByExpandedRows(this.dataSource)
}
}).finally(()=>{
this.loading = false
})
},
expandSubmenu(expanded, record){
if(expanded){
if (expanded && (!record.children || record.children.length === 0)) {
getSystemSubmenu({parentId:record.id}).then((res) => {
if (res.success) {
record.children = res.result
}
})
}
},
// 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
loadDataByExpandedRows(dataList) {
if (this.expandedRowKeys.length > 0) {
return getSystemSubmenuBatch({ parentIds: this.expandedRowKeys.join(',') }).then((res) => {
if (res.success) {
let childrenMap = res.result
let fn = (list) => {
list.forEach(data => {
if (this.expandedRowKeys.includes(data.id)) {
data.children = childrenMap[data.id]
fn(data.children)
}
})
}
fn(dataList)
}
})
} else {
return Promise.resolve()
}
},
// 打开数据规则编辑
handleDataRule(record) {
......@@ -189,10 +215,13 @@
this.$refs.modalForm.localMenuType = 1;
this.$refs.modalForm.disableSubmit = false;
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id});
}
},
handleExpandedRowsChange(expandedRows) {
this.expandedRowKeys = expandedRows
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
@import '~@assets/less/common.less';
</style>
\ No newline at end of file
......@@ -28,7 +28,9 @@
:pagination="false"
:dataSource="dataSource"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}">
:expandedRowKeys="expandedRowKeys"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@expandedRowsChange="handleExpandedRowsChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
......@@ -152,6 +154,8 @@
// 表头
columns: columns,
loading: false,
// 展开的行,受控属性
expandedRowKeys: [],
url: {
list: '/sys/permission/list',
delete: '/sys/permission/delete',
......@@ -178,10 +182,13 @@
this.$refs.modalForm.localMenuType = 1;
this.$refs.modalForm.disableSubmit = false;
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id});
}
},
handleExpandedRowsChange(expandedRows) {
this.expandedRowKeys = expandedRows
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
@import '~@assets/less/common.less';
</style>
\ No newline at end of file
......@@ -67,8 +67,8 @@
<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" />
......
......@@ -60,26 +60,27 @@
:rowSelection="{selectedRowKeys: selectedRowKeys1, onChange: onSelectChange1, type:'radio'}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleOpen(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="handlePerssion(record.id)">授权</a>
</a-menu-item>
<a-menu-item>
<a @click="handleEdit(record)">编辑</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete1(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
<a @click="handleOpen(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="handlePerssion(record.id)">授权</a>
</a-menu-item>
<a-menu-item>
<a @click="handleEdit(record)">编辑</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete1(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
......@@ -530,7 +531,7 @@
},
handlePerssion(roleId){
this.$refs.modalUserRole.show(roleId);
}
},
}
}
</script>
......
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="规则名称">
<a-input placeholder="请输入规则名称" v-model="queryParam.ruleName"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="规则Code">
<a-input placeholder="请输入规则Code" v-model="queryParam.ruleCode"/>
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
</template>
<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>
<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 @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('编码校验规则')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<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 -->
<a-alert type="info" showIcon style="margin-bottom: 16px;">
<template slot="message">
<span>已选择</span>
<a style="font-weight: 600;padding: 0 4px;">{{ selectedRowKeys.length }}</a>
<span></span>
<template v-if="selectedRowKeys.length>0">
<a-divider type="vertical"/>
<a @click="onClearSelected">清空</a>
</template>
</template>
</a-alert>
<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 @click="handleTest(record)">功能测试</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
<span>更多</span>
<a-icon type="down"/>
</a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="handleDelete(record.id)">删除</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
</a-table>
<!-- table区域-end -->
<!-- 表单区域 -->
<sys-check-rule-modal ref="modalForm" @ok="modalFormOk"/>
<sys-check-rule-test-modal ref="testModal"/>
</a-card>
</template>
<script>
import JEllipsis from '@/components/jeecg/JEllipsis'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import SysCheckRuleModal from './modules/SysCheckRuleModal'
import SysCheckRuleTestModal from './modules/SysCheckRuleTestModal'
export default {
name: 'SysCheckRuleList',
mixins: [JeecgListMixin],
components: { SysCheckRuleModal, SysCheckRuleTestModal, JEllipsis },
data() {
return {
description: '编码校验规则管理页面',
// 表头
columns: [
{
title: '#',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: (t, r, i) => i + 1
},
{
title: '规则名称',
align: 'center',
dataIndex: 'ruleName'
},
{
title: '规则Code',
align: 'center',
dataIndex: 'ruleCode'
},
{
title: '规则描述',
align: 'center',
dataIndex: 'ruleDescription',
customRender: (t) => (<j-ellipsis value={t} length={48}/>)
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' },
}
],
url: {
list: '/sys/checkRule/list',
delete: '/sys/checkRule/delete',
deleteBatch: '/sys/checkRule/deleteBatch',
exportXlsUrl: 'sys/checkRule/exportXls',
importExcelUrl: 'sys/checkRule/importExcel',
},
}
},
computed: {
importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
}
},
methods: {
handleTest(record) {
this.$refs.testModal.open(record.ruleCode)
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
\ No newline at end of file
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="数据源名称">
<a-input placeholder="请输入数据源名称" v-model="queryParam.name"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="数据库类型">
<j-dict-select-tag v-model="queryParam.dbType" placeholder="请选择数据库类型" dict-code="database_type"/>
</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>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('多数据源管理')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<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>
<a-alert type="info" showIcon style="margin-bottom: 16px;">
<template slot="message">
<span>已选择</span>
<a style="font-weight: 600;padding: 0 4px;">{{ selectedRowKeys.length }}</a>
<span></span>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</template>
</a-alert>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<sys-data-source-modal ref="modalForm" @ok="modalFormOk"/>
</a-card>
</template>
<script>
import JEllipsis from '@/components/jeecg/JEllipsis'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import SysDataSourceModal from './modules/SysDataSourceModal'
export default {
name: 'SysDataSourceList',
mixins: [JeecgListMixin],
components: { JEllipsis, SysDataSourceModal },
data() {
let ellipsis = (v, l = 20) => (<j-ellipsis value={v} length={l}/>)
return {
description: '多数据源管理管理页面',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: (t, r, index) => index + 1
},
{
title: '数据源名称',
align: 'center',
dataIndex: 'name'
},
{
title: '数据源编码',
align: 'center',
dataIndex: 'code'
},
{
title: '备注',
align: 'center',
dataIndex: 'remark',
customRender: (t) => ellipsis(t)
},
{
title: '数据库类型',
align: 'center',
dataIndex: 'dbType_dictText'
},
{
title: '驱动类',
align: 'center',
dataIndex: 'dbDriver',
customRender: (t) => ellipsis(t)
},
{
title: '数据源地址',
align: 'center',
dataIndex: 'dbUrl',
customRender: (t) => ellipsis(t)
},
{
title: '数据库名称',
align: 'center',
dataIndex: 'dbName'
},
{
title: '用户名',
align: 'center',
dataIndex: 'dbUsername'
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' },
}
],
url: {
list: '/sys/dataSource/list',
delete: '/sys/dataSource/delete',
deleteBatch: '/sys/dataSource/deleteBatch',
exportXlsUrl: 'sys/dataSource/exportXls',
importExcelUrl: 'sys/dataSource/importExcel',
},
}
},
computed: {
importExcelUrl() {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
}
},
methods: {}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
\ No newline at end of file
......@@ -30,7 +30,7 @@
</template>
<script>
import {changPassword} from '@/api/api'
import {changePassword} from '@/api/api'
export default {
name: "PasswordModal",
......@@ -96,7 +96,7 @@
if (!err) {
this.confirmLoading = true;
let formData = Object.assign(this.model, values);
changPassword(formData).then((res)=>{
changePassword(formData).then((res)=>{
if(res.success){
this.$message.success(res.message);
this.$emit('ok');
......
......@@ -26,7 +26,7 @@
},
computed: {
email () {
let v = this.form && this.form.username || 'xxx'
let v = this.form ? this.form.username || this.form.mobile : ' XXX '
let title = `你的账户:${v} 注册成功`
this.username = v;
return title
......
......@@ -30,7 +30,6 @@ module.exports = {
.set('@comp', resolve('src/components'))
.set('@views', resolve('src/views'))
.set('@layout', resolve('src/layout'))
.set('@static', resolve('src/static'))
},
css: {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册