mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
Jeecg-Boot 2.1.4 版本发布 | 重构较大,较多新功能
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
<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,
|
||||
|
||||
@ -1,71 +1,83 @@
|
||||
<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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<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,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<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,
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
export const ChartEventMixins = {
|
||||
methods: {
|
||||
handleClick(event, chart) {
|
||||
this.handleEvent('click', event, chart)
|
||||
},
|
||||
handleEvent(eventName, event, chart) {
|
||||
this.$emit(eventName, event, chart)
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
<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++){
|
||||
|
||||
@ -32,6 +32,8 @@
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<slot name="actionButtonAfter" :target="getVM()"/>
|
||||
|
||||
<div :id="`${caseId}inputTable`" class="input-table">
|
||||
<!-- 渲染表头 -->
|
||||
<div class="thead" ref="thead">
|
||||
@ -142,7 +144,9 @@
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true">
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
|
||||
<input
|
||||
:id="id"
|
||||
@ -175,7 +179,9 @@
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true">
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@ -211,7 +217,9 @@
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true">
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@ -278,19 +286,33 @@
|
||||
</template>
|
||||
|
||||
<div :hidden="uploadValues[id] != null">
|
||||
|
||||
<a-upload
|
||||
name="file"
|
||||
:data="{'isup':1}"
|
||||
:multiple="false"
|
||||
:action="col.action"
|
||||
:headers="uploadGetHeaders(row,col)"
|
||||
:showUploadList="false"
|
||||
v-bind="buildProps(row,col)"
|
||||
@change="(v)=>handleChangeUpload(v,id,row,col)"
|
||||
<a-tooltip
|
||||
:key="i"
|
||||
:id="id"
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
<a-button icon="upload">{{ col.placeholder }}</a-button>
|
||||
</a-upload>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@mouseout="()=>{handleMouseoutCommono(row,col)}">
|
||||
<a-upload
|
||||
name="file"
|
||||
:data="{'isup':1}"
|
||||
:multiple="false"
|
||||
:action="col.action"
|
||||
:headers="uploadGetHeaders(row,col)"
|
||||
:showUploadList="false"
|
||||
v-bind="buildProps(row,col)"
|
||||
@change="(v)=>handleChangeUpload(v,id,row,col)"
|
||||
>
|
||||
<a-button icon="upload">{{ col.placeholder }}</a-button>
|
||||
</a-upload>
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -303,7 +325,10 @@
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true">
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@mouseout="()=>{handleMouseoutCommono(row,col)}">
|
||||
@ -359,19 +384,33 @@
|
||||
</template>
|
||||
|
||||
<div :hidden="uploadValues[id] != null">
|
||||
|
||||
<a-upload
|
||||
name="file"
|
||||
:data="{'isup':1}"
|
||||
:multiple="false"
|
||||
:action="getUploadAction(col.action)"
|
||||
:headers="uploadGetHeaders(row,col)"
|
||||
:showUploadList="false"
|
||||
v-bind="buildProps(row,col)"
|
||||
@change="(v)=>handleChangeUpload(v,id,row,col)"
|
||||
<a-tooltip
|
||||
:key="i"
|
||||
:id="id"
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
<a-button icon="upload">{{ col.placeholder }}</a-button>
|
||||
</a-upload>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@mouseout="()=>{handleMouseoutCommono(row,col)}">
|
||||
<a-upload
|
||||
name="file"
|
||||
:data="{'isup':1}"
|
||||
:multiple="false"
|
||||
:action="getUploadAction(col.action)"
|
||||
:headers="uploadGetHeaders(row,col)"
|
||||
:showUploadList="false"
|
||||
v-bind="buildProps(row,col)"
|
||||
@change="(v)=>handleChangeUpload(v,id,row,col)"
|
||||
>
|
||||
<a-button icon="upload">{{ col.placeholder }}</a-button>
|
||||
</a-upload>
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -406,19 +445,33 @@
|
||||
</template>
|
||||
|
||||
<div :hidden="uploadValues[id] != null">
|
||||
|
||||
<a-upload
|
||||
name="file"
|
||||
:data="{'isup':1}"
|
||||
:multiple="false"
|
||||
:action="getUploadAction(col.action)"
|
||||
:headers="uploadGetHeaders(row,col)"
|
||||
:showUploadList="false"
|
||||
v-bind="buildProps(row,col)"
|
||||
@change="(v)=>handleChangeUpload(v,id,row,col)"
|
||||
<a-tooltip
|
||||
:key="i"
|
||||
:id="id"
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
<a-button icon="upload">请上传图片</a-button>
|
||||
</a-upload>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@mouseout="()=>{handleMouseoutCommono(row,col)}">
|
||||
<a-upload
|
||||
name="file"
|
||||
:data="{'isup':1}"
|
||||
:multiple="false"
|
||||
:action="getUploadAction(col.action)"
|
||||
:headers="uploadGetHeaders(row,col)"
|
||||
:showUploadList="false"
|
||||
v-bind="buildProps(row,col)"
|
||||
@change="(v)=>handleChangeUpload(v,id,row,col)"
|
||||
>
|
||||
<a-button icon="upload">请上传图片</a-button>
|
||||
</a-upload>
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -433,7 +486,10 @@
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true">
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@mouseout="()=>{handleMouseoutCommono(row,col)}">
|
||||
@ -459,7 +515,9 @@
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true">
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@ -492,7 +550,9 @@
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true">
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@ -526,7 +586,9 @@
|
||||
placement="top"
|
||||
:title="(tooltips[id] || {}).title"
|
||||
:visible="(tooltips[id] || {}).visible || false"
|
||||
:autoAdjustOverflow="true">
|
||||
:autoAdjustOverflow="true"
|
||||
:getPopupContainer="getParentContainer"
|
||||
>
|
||||
|
||||
<span
|
||||
@mouseover="()=>{handleMouseoverCommono(row,col)}"
|
||||
@ -693,6 +755,7 @@
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.inputValues = []
|
||||
// 当前显示的tr
|
||||
this.visibleTrEls = []
|
||||
this.disabledRowIds = (this.disabledRowIds || [])
|
||||
@ -771,149 +834,155 @@
|
||||
dataSource: {
|
||||
immediate: true,
|
||||
handler: function (newValue) {
|
||||
this.initialize()
|
||||
// 兼容IE
|
||||
this.getElementPromise('tbody').then(() => {
|
||||
|
||||
let rows = []
|
||||
let checkboxValues = {}
|
||||
let selectValues = {}
|
||||
let jdateValues = {}
|
||||
let slotValues = {}
|
||||
let uploadValues = {}
|
||||
let popupValues = {}
|
||||
let radioValues = {}
|
||||
let multiSelectValues = {}
|
||||
let searchSelectValues = {}
|
||||
this.initialize()
|
||||
|
||||
// 禁用行的id
|
||||
let disabledRowIds = (this.disabledRowIds || [])
|
||||
newValue.forEach((data, newValueIndex) => {
|
||||
// 判断源数据是否带有id
|
||||
if (data.id == null || data.id === '') {
|
||||
data.id = this.removeCaseId(this.generateId() + newValueIndex)
|
||||
}
|
||||
let rows = []
|
||||
let checkboxValues = {}
|
||||
let selectValues = {}
|
||||
let jdateValues = {}
|
||||
let slotValues = {}
|
||||
let uploadValues = {}
|
||||
let popupValues = {}
|
||||
let radioValues = {}
|
||||
let multiSelectValues = {}
|
||||
let searchSelectValues = {}
|
||||
|
||||
let value = { id: this.caseId + data.id }
|
||||
let row = { id: value.id }
|
||||
let disabled = false
|
||||
this.columns.forEach(column => {
|
||||
let inputId = column.key + value.id
|
||||
let sourceValue = (data[column.key] == null ? '' : data[column.key]).toString()
|
||||
if (column.type === FormTypes.checkbox) {
|
||||
|
||||
// 判断是否设定了customValue(自定义值)
|
||||
if (column.customValue instanceof Array) {
|
||||
let customValue = (column.customValue[0] || '').toString()
|
||||
checkboxValues[inputId] = (sourceValue === customValue)
|
||||
} else {
|
||||
checkboxValues[inputId] = sourceValue
|
||||
}
|
||||
|
||||
} else if (column.type === FormTypes.select) {
|
||||
if (sourceValue) {
|
||||
// 判断是否是多选
|
||||
selectValues[inputId] = (column.props || {})['mode'] === 'multiple' ? sourceValue.split(',') : sourceValue
|
||||
} else {
|
||||
selectValues[inputId] = undefined
|
||||
}
|
||||
|
||||
} else if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
|
||||
jdateValues[inputId] = sourceValue
|
||||
|
||||
} else if (column.type === FormTypes.slot) {
|
||||
if (sourceValue !== 0 && !sourceValue) {
|
||||
slotValues[inputId] = column.defaultValue
|
||||
} else {
|
||||
slotValues[inputId] = sourceValue
|
||||
}
|
||||
|
||||
} else if (column.type === FormTypes.popup) {
|
||||
popupValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.radio) {
|
||||
radioValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.sel_search) {
|
||||
searchSelectValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.list_multi) {
|
||||
if (sourceValue.length > 0) {
|
||||
multiSelectValues[inputId] = sourceValue.split(',')
|
||||
} else {
|
||||
multiSelectValues[inputId] = []
|
||||
}
|
||||
} else if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) {
|
||||
if (sourceValue) {
|
||||
let fileName = sourceValue.substring(sourceValue.lastIndexOf('/') + 1)
|
||||
uploadValues[inputId] = {
|
||||
name: fileName,
|
||||
status: 'done',
|
||||
path: sourceValue
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value[column.key] = sourceValue
|
||||
// 禁用行的id
|
||||
let disabledRowIds = (this.disabledRowIds || [])
|
||||
newValue.forEach((data, newValueIndex) => {
|
||||
// 判断源数据是否带有id
|
||||
if (data.id == null || data.id === '') {
|
||||
data.id = this.removeCaseId(this.generateId() + newValueIndex)
|
||||
}
|
||||
|
||||
// 解析disabledRows
|
||||
for (let columnKey in this.disabledRows) {
|
||||
// 判断是否有该属性
|
||||
if (this.disabledRows.hasOwnProperty(columnKey) && data.hasOwnProperty(columnKey)) {
|
||||
if (disabled !== true) {
|
||||
let temp = this.disabledRows[columnKey]
|
||||
// 禁用规则可以是一个数组
|
||||
if (temp instanceof Array) {
|
||||
disabled = temp.includes(data[columnKey])
|
||||
} else {
|
||||
disabled = (temp === data[columnKey])
|
||||
let value = { id: this.caseId + data.id }
|
||||
let row = { id: value.id }
|
||||
let disabled = false
|
||||
this.columns.forEach(column => {
|
||||
let inputId = column.key + value.id
|
||||
let sourceValue = (data[column.key] == null ? '' : data[column.key]).toString()
|
||||
if (column.type === FormTypes.checkbox) {
|
||||
|
||||
// 判断是否设定了customValue(自定义值)
|
||||
if (column.customValue instanceof Array) {
|
||||
let customValue = (column.customValue[0] || '').toString()
|
||||
checkboxValues[inputId] = (sourceValue === customValue)
|
||||
} else {
|
||||
checkboxValues[inputId] = sourceValue
|
||||
}
|
||||
|
||||
} else if (column.type === FormTypes.select) {
|
||||
if (sourceValue) {
|
||||
// 判断是否是多选
|
||||
selectValues[inputId] = (column.props || {})['mode'] === 'multiple' ? sourceValue.split(',') : sourceValue
|
||||
} else {
|
||||
selectValues[inputId] = undefined
|
||||
}
|
||||
|
||||
} else if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
|
||||
jdateValues[inputId] = sourceValue
|
||||
|
||||
} else if (column.type === FormTypes.slot) {
|
||||
if (sourceValue !== 0 && !sourceValue) {
|
||||
slotValues[inputId] = column.defaultValue
|
||||
} else {
|
||||
slotValues[inputId] = sourceValue
|
||||
}
|
||||
|
||||
} else if (column.type === FormTypes.popup) {
|
||||
popupValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.radio) {
|
||||
radioValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.sel_search) {
|
||||
searchSelectValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.list_multi) {
|
||||
if (sourceValue.length > 0) {
|
||||
multiSelectValues[inputId] = sourceValue.split(',')
|
||||
} else {
|
||||
multiSelectValues[inputId] = []
|
||||
}
|
||||
} else if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) {
|
||||
if (sourceValue) {
|
||||
let fileName = sourceValue.substring(sourceValue.lastIndexOf('/') + 1)
|
||||
uploadValues[inputId] = {
|
||||
name: fileName,
|
||||
status: 'done',
|
||||
path: sourceValue
|
||||
}
|
||||
if (disabled) {
|
||||
disabledRowIds.push(row.id)
|
||||
}
|
||||
} else {
|
||||
value[column.key] = sourceValue
|
||||
}
|
||||
|
||||
// 解析disabledRows
|
||||
for (let columnKey in this.disabledRows) {
|
||||
// 判断是否有该属性
|
||||
if (this.disabledRows.hasOwnProperty(columnKey) && data.hasOwnProperty(columnKey)) {
|
||||
if (disabled !== true) {
|
||||
let temp = this.disabledRows[columnKey]
|
||||
// 禁用规则可以是一个数组
|
||||
if (temp instanceof Array) {
|
||||
disabled = temp.includes(data[columnKey])
|
||||
} else {
|
||||
disabled = (temp === data[columnKey])
|
||||
}
|
||||
if (disabled) {
|
||||
disabledRowIds.push(row.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
this.inputValues.push(value)
|
||||
rows.push(row)
|
||||
})
|
||||
this.inputValues.push(value)
|
||||
rows.push(row)
|
||||
})
|
||||
this.disabledRowIds = disabledRowIds
|
||||
this.checkboxValues = checkboxValues
|
||||
this.selectValues = selectValues
|
||||
this.jdateValues = jdateValues
|
||||
this.slotValues = slotValues
|
||||
this.rows = rows
|
||||
this.uploadValues = uploadValues
|
||||
this.popupValues = popupValues
|
||||
this.radioValues = radioValues
|
||||
this.multiSelectValues = multiSelectValues
|
||||
this.searchSelectValues = searchSelectValues
|
||||
this.disabledRowIds = disabledRowIds
|
||||
this.checkboxValues = checkboxValues
|
||||
this.selectValues = selectValues
|
||||
this.jdateValues = jdateValues
|
||||
this.slotValues = slotValues
|
||||
this.rows = rows
|
||||
this.uploadValues = uploadValues
|
||||
this.popupValues = popupValues
|
||||
this.radioValues = radioValues
|
||||
this.multiSelectValues = multiSelectValues
|
||||
this.searchSelectValues = searchSelectValues
|
||||
|
||||
// 更新form表单的值
|
||||
this.$nextTick(() => {
|
||||
this.updateFormValues()
|
||||
// 更新form表单的值
|
||||
this.$nextTick(() => {
|
||||
this.updateFormValues()
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
columns: {
|
||||
immediate: true,
|
||||
handler(columns) {
|
||||
columns.forEach(column => {
|
||||
if (column.type === FormTypes.select || column.type === FormTypes.list_multi || column.type === FormTypes.sel_search) {
|
||||
// 兼容 旧版本 options
|
||||
if (column.options instanceof Array) {
|
||||
column.options = column.options.map(item => {
|
||||
if (item) {
|
||||
return {
|
||||
...item,
|
||||
text: item.text || item.title,
|
||||
title: item.text || item.title
|
||||
// 兼容IE
|
||||
this.getElementPromise('tbody').then(() => {
|
||||
columns.forEach(column => {
|
||||
if (column.type === FormTypes.select || column.type === FormTypes.list_multi || column.type === FormTypes.sel_search) {
|
||||
// 兼容 旧版本 options
|
||||
if (column.options instanceof Array) {
|
||||
column.options = column.options.map(item => {
|
||||
if (item) {
|
||||
return {
|
||||
...item,
|
||||
text: item.text || item.title,
|
||||
title: item.text || item.title
|
||||
}
|
||||
}
|
||||
}
|
||||
return {}
|
||||
})
|
||||
return {}
|
||||
})
|
||||
}
|
||||
if (column.dictCode) {
|
||||
this._loadDictConcatToOptions(column)
|
||||
}
|
||||
}
|
||||
if (column.dictCode) {
|
||||
this._loadDictConcatToOptions(column)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -923,19 +992,12 @@
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 获取document element对象
|
||||
let elements = {};
|
||||
['inputTable', 'tbody'].forEach(id => {
|
||||
elements[id] = document.getElementById(this.caseId + id)
|
||||
})
|
||||
this.el = elements
|
||||
|
||||
let vm = this
|
||||
/** 监听滚动条事件 */
|
||||
this.el.inputTable.onscroll = function (event) {
|
||||
this.getElement('inputTable').onscroll = function (event) {
|
||||
vm.syncScrollBar(event.target.scrollLeft)
|
||||
}
|
||||
this.el.tbody.onscroll = function (event) {
|
||||
this.getElement('tbody').onscroll = function (event) {
|
||||
// vm.recalcTrHiddenItem(event.target.scrollTop)
|
||||
}
|
||||
|
||||
@ -955,6 +1017,25 @@
|
||||
},
|
||||
methods: {
|
||||
|
||||
getElement(id, noCaseId = false) {
|
||||
if (!this.el[id]) {
|
||||
this.el[id] = document.getElementById((noCaseId ? '' : this.caseId) + id)
|
||||
}
|
||||
return this.el[id]
|
||||
},
|
||||
|
||||
getElementPromise(id, noCaseId = false) {
|
||||
return new Promise((resolve) => {
|
||||
let timer = setInterval(() => {
|
||||
let element = this.getElement(id, noCaseId)
|
||||
if (element) {
|
||||
clearInterval(timer)
|
||||
resolve(element)
|
||||
}
|
||||
}, 10)
|
||||
})
|
||||
},
|
||||
|
||||
/** 初始化列表 */
|
||||
initialize() {
|
||||
// inputValues:用来存储input表单的值
|
||||
@ -985,14 +1066,14 @@
|
||||
this.searchSelectValues = []
|
||||
this.scrollTop = 0
|
||||
this.$nextTick(() => {
|
||||
this.el.tbody.scrollTop = 0
|
||||
this.getElement('tbody').scrollTop = 0
|
||||
})
|
||||
},
|
||||
|
||||
/** 同步滚动条状态 */
|
||||
syncScrollBar(scrollLeft) {
|
||||
// this.style.tbody.left = `${scrollLeft}px`
|
||||
// this.el.tbody.scrollLeft = scrollLeft
|
||||
// this.getElement('tbody').scrollLeft = scrollLeft
|
||||
},
|
||||
/** 重置滚动条位置,参数留空则滚动到上次记录的位置 */
|
||||
resetScrollTop(top) {
|
||||
@ -1157,7 +1238,7 @@
|
||||
target: this
|
||||
})
|
||||
// 设置滚动条位置
|
||||
let tbody = this.el.tbody
|
||||
let tbody = this.getElement('tbody')
|
||||
let offsetHeight = tbody.offsetHeight
|
||||
let realScrollTop = tbody.scrollTop + offsetHeight
|
||||
if (forceScrollToBottom === false) {
|
||||
@ -1245,13 +1326,14 @@
|
||||
return true
|
||||
},
|
||||
|
||||
/** 获取表格表单里的值(同步版) */
|
||||
getValuesSync(options = {}) {
|
||||
/** 获取表格表单里的值(异步版) */
|
||||
getValuesAsync(options = {}, callback) {
|
||||
let { validate, rowIds } = options
|
||||
if (typeof validate !== 'boolean') validate = true
|
||||
if (!(rowIds instanceof Array)) rowIds = null
|
||||
// console.log('options:', { validate, rowIds })
|
||||
|
||||
let asyncCount = 0
|
||||
let error = 0
|
||||
let inputValues = cloneObject(this.inputValues)
|
||||
let tooltips = Object.assign({}, this.tooltips)
|
||||
@ -1314,7 +1396,7 @@
|
||||
} else if (column.type === FormTypes.sel_search) {
|
||||
value[column.key] = this.searchSelectValues[inputId]
|
||||
} else if (column.type === FormTypes.list_multi) {
|
||||
if (!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length == 0) {
|
||||
if (!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length === 0) {
|
||||
value[column.key] = ''
|
||||
} else {
|
||||
value[column.key] = this.multiSelectValues[inputId].join(',')
|
||||
@ -1326,20 +1408,27 @@
|
||||
|
||||
// 检查表单验证
|
||||
if (validate === true) {
|
||||
let results = this.validateOneInput(value[column.key], value, column, notPassedIds, false, 'getValues')
|
||||
tooltips[inputId] = results[0]
|
||||
if (tooltips[inputId].passed === false) {
|
||||
error++
|
||||
// if (error++ === 0) {
|
||||
// let element = document.getElementById(inputId)
|
||||
// while (element.className !== 'tr') {
|
||||
// element = element.parentElement
|
||||
// }
|
||||
// this.jumpToId(inputId, element)
|
||||
// }
|
||||
const handleValidateOneInput = (results) => {
|
||||
tooltips[inputId] = results[0]
|
||||
if (tooltips[inputId].passed === false) {
|
||||
error++
|
||||
// if (error++ === 0) {
|
||||
// let element = document.getElementById(inputId)
|
||||
// while (element.className !== 'tr') {
|
||||
// element = element.parentElement
|
||||
// }
|
||||
// this.jumpToId(inputId, element)
|
||||
// }
|
||||
}
|
||||
tooltips[inputId].visible = false
|
||||
notPassedIds = results[1]
|
||||
}
|
||||
tooltips[inputId].visible = false
|
||||
notPassedIds = results[1]
|
||||
asyncCount++
|
||||
let results = this.validateOneInputAsync(value[column.key], value, column, notPassedIds, false, 'getValues', (results) => {
|
||||
handleValidateOneInput(results)
|
||||
asyncCount--
|
||||
})
|
||||
handleValidateOneInput(results)
|
||||
}
|
||||
})
|
||||
// 将caseId去除
|
||||
@ -1352,25 +1441,42 @@
|
||||
this.tooltips = tooltips
|
||||
this.notPassedIds = notPassedIds
|
||||
}
|
||||
|
||||
const timer = setInterval(() => {
|
||||
if (asyncCount === 0) {
|
||||
clearInterval(timer)
|
||||
if (typeof callback === 'function') {
|
||||
callback({ error, values })
|
||||
}
|
||||
}
|
||||
}, 50)
|
||||
|
||||
return { error, values }
|
||||
},
|
||||
|
||||
/** 获取表格表单里的值(同步版) */
|
||||
getValuesSync(options = {}) {
|
||||
return this.getValuesAsync(options)
|
||||
},
|
||||
|
||||
/** 获取表格表单里的值 */
|
||||
getValues(callback, validate = true, rowIds) {
|
||||
let result = this.getValuesSync({ validate, rowIds })
|
||||
if (typeof callback === 'function') {
|
||||
callback(result.error, result.values)
|
||||
}
|
||||
this.getValuesAsync({ validate, rowIds }, ({ error, values }) => {
|
||||
if (typeof callback === 'function') {
|
||||
callback(error, values)
|
||||
}
|
||||
})
|
||||
},
|
||||
/** getValues的Promise版 */
|
||||
getValuesPromise(validate = true, rowIds) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let { error, values } = this.getValuesSync({ validate, rowIds })
|
||||
if (error === 0) {
|
||||
resolve(values)
|
||||
} else {
|
||||
reject(VALIDATE_NO_PASSED)
|
||||
}
|
||||
this.getValuesAsync({ validate, rowIds }, ({ error, values }) => {
|
||||
if (error === 0) {
|
||||
resolve(values)
|
||||
} else {
|
||||
reject(VALIDATE_NO_PASSED)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
/** 获取被删除项的id */
|
||||
@ -1468,14 +1574,24 @@
|
||||
// element = document.getElementById(id)
|
||||
// }
|
||||
// if (element != null) {
|
||||
// console.log(this.el.tbody.scrollTop, element.offsetTop)
|
||||
// this.el.tbody.scrollTop = element.offsetTop
|
||||
// console.log(this.el.tbody.scrollTop, element.offsetTop)
|
||||
// console.log(this.getElement('tbody').scrollTop, element.offsetTop)
|
||||
// this.getElement('tbody').scrollTop = element.offsetTop
|
||||
// console.log(this.getElement('tbody').scrollTop, element.offsetTop)
|
||||
// }
|
||||
// },
|
||||
|
||||
/** 验证单个表单 */
|
||||
validateOneInput(value, row, column, notPassedIds, update = false, validType = 'input') {
|
||||
/**
|
||||
* 验证单个表单,异步版
|
||||
*
|
||||
* @param value 校验的值
|
||||
* @param row 校验的行
|
||||
* @param column 校验的列
|
||||
* @param notPassedIds 没有通过校验的 id
|
||||
* @param update 是否更新到vue中
|
||||
* @param validType 校验触发的方式(input、blur等)
|
||||
* @param callback
|
||||
*/
|
||||
validateOneInputAsync(value, row, column, notPassedIds, update = false, validType = 'input', callback) {
|
||||
let tooltips = Object.assign({}, this.tooltips)
|
||||
// let notPassedIds = cloneObject(this.notPassedIds)
|
||||
let inputId = column.key + row.id
|
||||
@ -1515,6 +1631,10 @@
|
||||
if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
|
||||
element = element.getElementsByTagName('input')[0]
|
||||
}
|
||||
// upload 在 .ant-upload .ant-btn 上设置 border-color
|
||||
if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) {
|
||||
element = element.getElementsByClassName('ant-upload')[0].getElementsByClassName('ant-btn')[0]
|
||||
}
|
||||
element.style.borderColor = borderColor
|
||||
element.style.boxShadow = boxShadow
|
||||
if (element.tagName === 'SPAN') {
|
||||
@ -1527,6 +1647,10 @@
|
||||
this.notPassedIds = notPassedIds
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback([tooltips[inputId], notPassedIds])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (typeof passed === 'function') {
|
||||
@ -1547,9 +1671,13 @@
|
||||
nextThen([passed, message])
|
||||
}
|
||||
|
||||
|
||||
return [tooltips[inputId], notPassedIds]
|
||||
},
|
||||
|
||||
/** 验证单个表单 */
|
||||
validateOneInput(value, row, column, notPassedIds, update = false, validType = 'input') {
|
||||
return this.validateOneInputAsync(value, row, column, notPassedIds, update, validType)
|
||||
},
|
||||
/** 通过规则验证值是否正确 */
|
||||
validateValue(column, value) {
|
||||
let rules = column.validateRules
|
||||
@ -1620,7 +1748,7 @@
|
||||
|
||||
/** 动态更新表单的值 */
|
||||
updateFormValues() {
|
||||
let trs = this.el.tbody.getElementsByClassName('tr')
|
||||
let trs = this.getElement('tbody').getElementsByClassName('tr')
|
||||
let trEls = []
|
||||
for (let tr of trs) {
|
||||
trEls.push(tr)
|
||||
@ -1959,7 +2087,7 @@
|
||||
handleClickDownloadFile(id) {
|
||||
let { path } = this.uploadValues[id] || {}
|
||||
if (path) {
|
||||
let url = window._CONFIG['downloadUrl'] + '/' + path
|
||||
let url = window._CONFIG['staticDomainURL'] + '/' + path
|
||||
window.open(url)
|
||||
}
|
||||
},
|
||||
@ -2130,7 +2258,7 @@
|
||||
getCellImageView(id) {
|
||||
let currUploadObj = this.uploadValues[id] || null
|
||||
if (currUploadObj && currUploadObj['path']) {
|
||||
return window._CONFIG['domianURL'] + '/sys/common/view/' + currUploadObj['path']
|
||||
return window._CONFIG['staticDomainURL'] + '/' + currUploadObj['path']
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
@ -2340,7 +2468,7 @@
|
||||
|
||||
.td {
|
||||
/*flex: 1;*/
|
||||
padding: 14px 0 14px @spacing;
|
||||
padding: 14px @spacing 14px 0;
|
||||
justify-content: center;
|
||||
|
||||
&:last-child {
|
||||
|
||||
@ -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("生成验证码错误,请联系系统管理员")
|
||||
|
||||
202
ant-design-vue-jeecg/src/components/jeecg/JImageUpload.vue
Normal file
202
ant-design-vue-jeecg/src/components/jeecg/JImageUpload.vue
Normal file
@ -0,0 +1,202 @@
|
||||
<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>
|
||||
@ -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);
|
||||
});
|
||||
|
||||
209
ant-design-vue-jeecg/src/components/jeecg/JModal/index.vue
Normal file
209
ant-design-vue-jeecg/src/components/jeecg/JModal/index.vue
Normal file
@ -0,0 +1,209 @@
|
||||
<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>
|
||||
@ -1,15 +1,22 @@
|
||||
<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){
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
import T from './JFormContainer.vue'
|
||||
let install = function (Vue) {
|
||||
Vue.component('JFormContainer',T);
|
||||
}
|
||||
export default { install };
|
||||
import JModal from './JModal'
|
||||
import JFormContainer from './JFormContainer.vue'
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
Vue.component('JFormContainer', JFormContainer)
|
||||
Vue.component(JModal.name, JModal)
|
||||
}
|
||||
}
|
||||
@ -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 © 2019 <a href="http://www.jeecg.org" target="_blank">JEECG开源社区</a> 出品
|
||||
Copyright © 2019 <a href="http://www.jeecg.com" target="_blank">JEECG开源社区</a> 出品
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
ant-design-vue-jeecg/src/components/tools/DynamicNotice.vue
Normal file
36
ant-design-vue-jeecg/src/components/tools/DynamicNotice.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<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>
|
||||
@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user