Jeecg-Boot 2.1.0 版本发布,Online表单开发&在线代码生成器(迟到的版本)

This commit is contained in:
zhangdaihao
2019-08-24 00:15:45 +08:00
parent 839357789c
commit 5069209093
165 changed files with 13536 additions and 17580 deletions

View File

@ -209,10 +209,10 @@
})
getVisitInfo().then(res=>{
if(res.success){
console.log("aaaaaa",res.result)
this.visitInfo = res.result;
}
})
console.log("aaaaaa",res.result)
this.visitInfo = res.result;
}
})
},
}
}

View File

@ -1,307 +1,37 @@
<template>
<div>
<a-card :borderd="false">
<a-card :bordered="false">
<a-tabs>
<a-button @click="handleTableCheck" type="primary">表单验证</a-button>
<span style="padding-left:8px;"></span>
<a-tooltip placement="top" title="获取值,忽略表单验证" :autoAdjustOverflow="true">
<a-button @click="handleTableGet" type="primary">获取值</a-button>
</a-tooltip>
<span style="padding-left:8px;"></span>
<a-tooltip placement="top" title="模拟加载1000条数据" :autoAdjustOverflow="true">
<a-button @click="handleTableSet" type="primary">设置值</a-button>
</a-tooltip>
<a-tab-pane tab="普通列表" key="1">
<default-table/>
</a-tab-pane>
<a-tab-pane tab="只读列表" key="2">
<read-only-table/>
</a-tab-pane>
<j-editable-table
ref="editableTable"
:loading="loading"
:columns="columns"
:dataSource="dataSource"
:rowNumber="true"
:rowSelection="true"
:actionButton="true"
style="margin-top: 8px;"
@selectRowChange="handleSelectRowChange">
<a-tab-pane tab="三级联动" key="3">
<three-linkage/>
</a-tab-pane>
<template v-slot:action="props">
<a @click="handleDelete(props)">{{ props.text }}</a>
</template>
</a-tabs>
</j-editable-table>
</a-card>
<br>
<a-card title="只读列表">
<j-editable-table
:columns="columns1"
:dataSource="dataSource1"
:rowNumber="true"
:rowSelection="true"
:maxHeight="200"
:disabled="true"
/>
</a-card>
</div>
</a-card>
</template>
<script>
import moment from 'moment'
import JEditableTable from '@/components/jeecg/JEditableTable'
import { FormTypes } from '@/utils/JEditableTableUtil'
import { randomUUID, randomNumber } from '@/utils/util'
import DefaultTable from './modules/JEditableTable/DefaultTable'
import ReadOnlyTable from './modules/JEditableTable/ReadOnlyTable'
import ThreeLinkage from './modules/JEditableTable/ThreeLinkage'
export default {
name: 'JeecgEditableTableExample',
components: {
JEditableTable
},
components: { DefaultTable, ReadOnlyTable, ThreeLinkage },
data() {
return {
loading: false,
columns: [
{
title: '字段名称',
key: 'dbFieldName',
// width: '19%',
width: '300px',
type: FormTypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [
{
required: true, // 必填
message: '请输入${title}' // 显示的文本
},
{
pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
message: '${title}必须以字母开头可包含数字下划线横杠'
}
]
},
{
title: '文件域',
key: 'upload',
type: FormTypes.upload,
// width: '19%',
width: '300px',
placeholder: '点击上传',
token: true,
responseName: 'message',
action: window._CONFIG['domianURL'] + '/sys/common/upload'
},
{
title: '字段类型',
key: 'dbFieldType',
// width: '18%',
width: '300px',
type: FormTypes.select,
options: [ // 下拉选项
{ title: 'String', value: 'string' },
{ title: 'Integer', value: 'int' },
{ title: 'Double', value: 'double' },
{ title: 'Boolean', value: 'boolean' }
],
allowInput: true,
defaultValue: '',
placeholder: '请选择${title}',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '性别字典',
key: 'sex_dict',
width: '300px',
type: FormTypes.select,
options: [],
dictCode: 'sex',
placeholder: '请选择${title}',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '多选测试',
key: 'multipleSelect',
// width: '18%',
width: '300px',
type: FormTypes.select,
props: { 'mode': 'multiple' }, // 支持多选
options: [
{ title: 'String', value: 'string' },
{ title: 'Integer', value: 'int' },
{ title: 'Double', value: 'double' },
{ title: 'Boolean', value: 'boolean' }
],
defaultValue: ['int', 'boolean'], // 多个默认项
// defaultValue: 'string,double,int', // 也可使用这种方式
placeholder: '这里可以多选',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '字段长度',
key: 'dbLength',
// width: '8%',
width: '100px',
type: FormTypes.inputNumber,
defaultValue: 32,
placeholder: '${title}',
validateRules: [{ required: true, message: '请输入${title}' }]
},
{
title: '日期',
key: 'datetime',
// width: '22%',
width: '320px',
type: FormTypes.datetime,
defaultValue: '2019-4-30 14:52:22',
placeholder: '请选择${title}',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '可以为空',
key: 'isNull',
// width: '8%',
width: '100px',
type: FormTypes.checkbox,
customValue: ['Y', 'N'], // true ,false
defaultChecked: false
},
{
title: '操作',
key: 'action',
// width: '8%',
width: '100px',
type: FormTypes.slot,
slotName: 'action',
defaultValue: '删除'
}
],
dataSource: [],
selectedRowIds: [],
// table2
columns1: [
{
title: '输入框',
key: 'input',
type: FormTypes.input,
placeholder: '清输入'
},
{
title: '下拉框',
key: 'select',
type: FormTypes.select,
options: [
{ title: 'String', value: 'string' },
{ title: 'Integer', value: 'int' },
{ title: 'Double', value: 'double' },
{ title: 'Boolean', value: 'boolean' }
],
placeholder: '请选择'
},
{
title: '多选框',
key: 'checkbox',
type: FormTypes.checkbox,
customValue: [true, false]
},
{
title: '日期',
key: 'datetime',
type: FormTypes.datetime
}
],
dataSource1: []
}
return {}
},
created() {
},
mounted() {
this.randomData(23, false)
this.dataSource1 = [
{ input: 'hello', select: 'int', checkbox: true, datetime: '2019-6-17 14:50:48' },
{ input: 'world', select: 'string', checkbox: false, datetime: '2019-6-16 14:50:48' },
{ input: 'one', select: 'double', checkbox: true, datetime: '2019-6-17 15:50:48' },
{ input: 'two', select: 'boolean', checkbox: false, datetime: '2019-6-14 14:50:48' },
{ input: 'three', select: '', checkbox: false, datetime: '2019-6-13 14:50:48' }
]
},
methods: {
/** 表单验证 */
handleTableCheck() {
this.$refs.editableTable.getValues((error) => {
if (error === 0) {
this.$message.success('验证通过')
} else {
this.$message.error('验证未通过')
}
})
},
/** 获取值,忽略表单验证 */
handleTableGet() {
this.$refs.editableTable.getValues((error, values) => {
console.log('values:', values)
}, false)
console.log('deleteIds:', this.$refs.editableTable.getDeleteIds())
this.$message.info('获取值成功请看控制台输出')
},
/** 模拟加载1000条数据 */
handleTableSet() {
this.randomData(1000, true)
},
handleSelectRowChange(selectedRowIds) {
this.selectedRowIds = selectedRowIds
},
/* 随机生成数据 */
randomData(size, loading = false) {
if (loading) {
this.loading = true
}
let randomDatetime = () => {
let time = parseInt(randomNumber(1000, 9999999999999))
return moment(new Date(time)).format('YYYY-MM-DD HH:mm:ss')
}
let begin = Date.now()
let values = []
for (let i = 0; i < size; i++) {
values.push({
id: randomUUID(),
dbFieldName: `name_${i + 1}`,
// dbFieldTxt: randomString(10),
multipleSelect: ['string', ['int', 'double', 'boolean'][randomNumber(0, 2)]],
dbFieldType: ['string', 'int', 'double', 'boolean'][randomNumber(0, 3)],
dbLength: randomNumber(0, 233),
datetime: randomDatetime(),
isNull: ['Y', 'N'][randomNumber(0, 1)]
})
}
this.dataSource = values
let end = Date.now()
let diff = end - begin
if (loading && diff < size) {
setTimeout(() => {
this.loading = false
}, size - diff)
}
},
handleDelete(props) {
let { rowId, target } = props
target.removeRows(rowId)
}
}
methods: {}
}
</script>

View File

@ -49,7 +49,7 @@
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="选择部门">
<j-select-depart v-model="departId"></j-select-depart>
<j-select-depart v-model="departId" :multi="true"></j-select-depart>
</a-form-item>
</a-col>
<a-col :span="12">选中的部门ID(v-model):{{ departId }}</a-col>
@ -217,10 +217,8 @@
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="cron表达式">
<a-input @click="openModal" placeholder="corn表达式" v-model="cron.label" readOnly >
<a-icon slot="prefix" type="schedule" title="corn控件"/>
</a-input>
<VueCron ref="innerVueCron" :data="cron" @change="changeCron" ></VueCron>
<j-cron ref="innerVueCron" v-decorator="['cronExpression', {'initialValue':'0/1 * * * * ?'}]" @change="setCorn"></j-cron>
<!-- <j-cron ref="innerVueCron" v-model="cron" @change="setCorn"></j-cron>-->
</a-form-item>
</a-col>
</a-row>
@ -245,7 +243,7 @@
import JSlider from '@/components/jeecg/JSlider'
import JSelectMultiple from '@/components/jeecg/JSelectMultiple'
import JTreeDict from "../../components/jeecg/JTreeDict.vue";
import VueCron from "./modules/VueCronModal.vue";
import JCron from "@/components/jeecg/JCron.vue";
export default {
name: 'SelectDemo',
components: {
@ -257,7 +255,7 @@
JCheckbox,
JCodeEditor,
JDate, JEditor, JEllipsis, JGraphicCode, JSlider, JSelectMultiple,
VueCron
JCron
},
data() {
return {
@ -314,10 +312,7 @@ sayHi('hello, world!')`
style: { top: '20px' },
fullScreen: true
},
cron: {
label: '',
value: {}
}
cron: '',
}
},
computed: {
@ -372,14 +367,12 @@ sayHi('hello, world!')`
}
this.modal.fullScreen = mode
},
openModal(){
this.$refs.innerVueCron.show()
},
changeCron(val){
this.cron=val;
console.log(val);
}
setCorn(data){
this.$nextTick(() => {
this.form.cronExpression = data;
})
}
}
}
</script>

View File

@ -0,0 +1,91 @@
<template>
<a-card :bordered="false">
<a-table
rowKey="id"
bordered
:columns="columns"
:dataSource="dataSource"
:pagination="false"
>
</a-table>
</a-card>
</template>
<script>
export default {
name: 'TableTotal',
data() {
return {
columns: [
{
title: '#',
width: '180px',
align: 'center',
dataIndex: 'rowIndex',
customRender: function (text, r, index) {
return (text !== '合计') ? (parseInt(index) + 1) : text
}
},
{
title: '姓名',
dataIndex: 'name',
},
{
title: '贡献点',
dataIndex: 'point',
},
{
title: '等级',
dataIndex: 'level',
},
{
title: '更新时间',
dataIndex: 'updateTime',
},
],
dataSource: [
{ name: '张三', point: 23, level: 3, updateTime: '2019-8-14' },
{ name: '小王', point: 6, level: 1, updateTime: '2019-8-13' },
{ name: '李四', point: 53, level: 8, updateTime: '2019-8-12' },
{ name: '小红', point: 44, level: 5, updateTime: '2019-8-11' },
{ name: '王五', point: 97, level: 10, updateTime: '2019-8-10' },
{ name: '小明', point: 33, level: 2, updateTime: '2019-8-10' },
]
}
},
mounted() {
this.tableAddTotalRow(this.columns, this.dataSource)
},
methods: {
/** 表格增加合计行 */
tableAddTotalRow(columns, dataSource) {
let numKey = 'rowIndex'
let totalRow = { [numKey]: '合计' }
columns.forEach(column => {
let { key, dataIndex } = column
if (![key, dataIndex].includes(numKey)) {
let total = 0
dataSource.forEach(data => {
total += /^\d+\.?\d?$/.test(data[dataIndex]) ? Number.parseInt(data[dataIndex]) : Number.NaN
console.log(data[dataIndex], ':', (/^\d+\.?\d?$/.test(data[dataIndex]) ? Number.parseInt(data[dataIndex]) : Number.NaN))
})
if (Number.isNaN(total)) {
total = '-'
}
totalRow[dataIndex] = total
}
})
dataSource.push(totalRow)
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,250 @@
<template>
<div>
<a-button @click="handleTableCheck" type="primary">表单验证</a-button>
<span style="padding-left:8px;"></span>
<a-tooltip placement="top" title="获取值,忽略表单验证" :autoAdjustOverflow="true">
<a-button @click="handleTableGet" type="primary">获取值</a-button>
</a-tooltip>
<span style="padding-left:8px;"></span>
<a-tooltip placement="top" title="模拟加载1000条数据" :autoAdjustOverflow="true">
<a-button @click="handleTableSet" type="primary">设置值</a-button>
</a-tooltip>
<j-editable-table
ref="editableTable"
:loading="loading"
:columns="columns"
:dataSource="dataSource"
:rowNumber="true"
:rowSelection="true"
:actionButton="true"
:dragSort="true"
style="margin-top: 8px;"
@selectRowChange="handleSelectRowChange">
<template v-slot:action="props">
<a @click="handleDelete(props)">{{ props.text }}</a>
</template>
</j-editable-table>
</div>
</template>
<script>
import moment from 'moment'
import { FormTypes } from '@/utils/JEditableTableUtil'
import { randomUUID, randomNumber } from '@/utils/util'
import JEditableTable from '@/components/jeecg/JEditableTable'
export default {
name: 'DefaultTable',
components: { JEditableTable },
data() {
return {
loading: false,
columns: [
{
title: '字段名称',
key: 'dbFieldName',
// width: '19%',
width: '300px',
type: FormTypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [
{
required: true, // 必填
message: '请输入${title}' // 显示的文本
},
{
pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
message: '${title}必须以字母开头可包含数字下划线横杠'
}
]
},
{
title: '文件域',
key: 'upload',
type: FormTypes.upload,
// width: '19%',
width: '300px',
placeholder: '点击上传',
token: true,
responseName: 'message',
action: window._CONFIG['domianURL'] + '/sys/common/upload'
},
{
title: '字段类型',
key: 'dbFieldType',
// width: '18%',
width: '300px',
type: FormTypes.select,
options: [ // 下拉选项
{ title: 'String', value: 'string' },
{ title: 'Integer', value: 'int' },
{ title: 'Double', value: 'double' },
{ title: 'Boolean', value: 'boolean' }
],
allowInput: true,
defaultValue: '',
placeholder: '请选择${title}',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '性别字典',
key: 'sex_dict',
width: '300px',
type: FormTypes.select,
options: [],
dictCode: 'sex',
placeholder: '请选择${title}',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '多选测试',
key: 'multipleSelect',
// width: '18%',
width: '300px',
type: FormTypes.select,
props: { 'mode': 'multiple' }, // 支持多选
options: [
{ title: 'String', value: 'string' },
{ title: 'Integer', value: 'int' },
{ title: 'Double', value: 'double' },
{ title: 'Boolean', value: 'boolean' }
],
defaultValue: ['int', 'boolean'], // 多个默认项
// defaultValue: 'string,double,int', // 也可使用这种方式
placeholder: '这里可以多选',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '字段长度',
key: 'dbLength',
// width: '8%',
width: '100px',
type: FormTypes.inputNumber,
defaultValue: 32,
placeholder: '${title}',
validateRules: [{ required: true, message: '请输入${title}' }]
},
{
title: '日期',
key: 'datetime',
// width: '22%',
width: '320px',
type: FormTypes.datetime,
defaultValue: '2019-4-30 14:52:22',
placeholder: '请选择${title}',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '可以为空',
key: 'isNull',
// width: '8%',
width: '100px',
type: FormTypes.checkbox,
customValue: ['Y', 'N'], // true ,false
defaultChecked: false
},
{
title: '操作',
key: 'action',
// width: '8%',
width: '100px',
type: FormTypes.slot,
slotName: 'action',
defaultValue: '删除'
}
],
dataSource: [],
selectedRowIds: []
}
},
mounted() {
this.randomData(23, false)
},
methods: {
/** 表单验证 */
handleTableCheck() {
this.$refs.editableTable.getValues((error) => {
if (error === 0) {
this.$message.success('验证通过')
} else {
this.$message.error('验证未通过')
}
})
},
/** 获取值,忽略表单验证 */
handleTableGet() {
this.$refs.editableTable.getValues((error, values) => {
console.log('values:', values)
}, false)
console.log('deleteIds:', this.$refs.editableTable.getDeleteIds())
this.$message.info('获取值成功请看控制台输出')
},
/** 模拟加载1000条数据 */
handleTableSet() {
this.randomData(1000, true)
},
handleSelectRowChange(selectedRowIds) {
this.selectedRowIds = selectedRowIds
},
/* 随机生成数据 */
randomData(size, loading = false) {
if (loading) {
this.loading = true
}
let randomDatetime = () => {
let time = parseInt(randomNumber(1000, 9999999999999))
return moment(new Date(time)).format('YYYY-MM-DD HH:mm:ss')
}
let begin = Date.now()
let values = []
for (let i = 0; i < size; i++) {
values.push({
id: randomUUID(),
dbFieldName: `name_${i + 1}`,
// dbFieldTxt: randomString(10),
multipleSelect: ['string', ['int', 'double', 'boolean'][randomNumber(0, 2)]],
dbFieldType: ['string', 'int', 'double', 'boolean'][randomNumber(0, 3)],
dbLength: randomNumber(0, 233),
datetime: randomDatetime(),
isNull: ['Y', 'N'][randomNumber(0, 1)]
})
}
this.dataSource = values
let end = Date.now()
let diff = end - begin
if (loading && diff < size) {
setTimeout(() => {
this.loading = false
}, size - diff)
}
},
handleDelete(props) {
let { rowId, target } = props
target.removeRows(rowId)
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,70 @@
<template>
<j-editable-table
:columns="columns"
:dataSource="dataSource"
:rowNumber="true"
:rowSelection="true"
:maxHeight="400"
:disabled="true"
/>
</template>
<script>
import { FormTypes } from '@/utils/JEditableTableUtil'
import JEditableTable from '@/components/jeecg/JEditableTable'
export default {
name: 'ReadOnlyTable',
components: { JEditableTable },
data() {
return {
columns: [
{
title: '输入框',
key: 'input',
type: FormTypes.input,
placeholder: '清输入'
},
{
title: '下拉框',
key: 'select',
type: FormTypes.select,
options: [
{ title: 'String', value: 'string' },
{ title: 'Integer', value: 'int' },
{ title: 'Double', value: 'double' },
{ title: 'Boolean', value: 'boolean' }
],
placeholder: '请选择'
},
{
title: '多选框',
key: 'checkbox',
type: FormTypes.checkbox,
customValue: [true, false]
},
{
title: '日期',
key: 'datetime',
type: FormTypes.datetime
}
],
dataSource: [
{ input: 'hello', select: 'int', checkbox: true, datetime: '2019-6-17 14:50:48' },
{ input: 'world', select: 'string', checkbox: false, datetime: '2019-6-16 14:50:48' },
{ input: 'one', select: 'double', checkbox: true, datetime: '2019-6-17 15:50:48' },
{ input: 'two', select: 'boolean', checkbox: false, datetime: '2019-6-14 14:50:48' },
{ input: 'three', select: '', checkbox: false, datetime: '2019-6-13 14:50:48' }
]
}
},
mounted() {
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,129 @@
<template>
<j-editable-table
:columns="columns"
:dataSource="dataSource"
:rowNumber="true"
:actionButton="true"
:rowSelection="true"
:maxHeight="400"
@valueChange="handleValueChange"
/>
</template>
<script>
import { FormTypes } from '@/utils/JEditableTableUtil'
import JEditableTable from '@/components/jeecg/JEditableTable'
export default {
name: 'ThreeLinkage',
components: { JEditableTable },
data() {
return {
columns: [
{
title: '/直辖市/自治区',
key: 's1',
type: FormTypes.select,
width: '240px',
options: [],
placeholder: '请选择${title}'
},
{
title: '市',
key: 's2',
type: FormTypes.select,
width: '240px',
options: [],
placeholder: '请选择${title}'
},
{
title: '/',
key: 's3',
type: FormTypes.select,
width: '240px',
options: [],
placeholder: '请选择${title}'
}
],
dataSource: [],
mockData: [
{ label: '北京市', value: '110000', parent: null },
{ label: '天津市', value: '120000', parent: null },
{ label: '河北省', value: '130000', parent: null },
{ label: '上海市', value: '310000', parent: null },
{ label: '北京市', value: '110100', parent: '110000' },
{ label: '天津市市', value: '120100', parent: '120000' },
{ label: '石家庄市', value: '130100', parent: '130000' },
{ label: '唐山市', value: '130200', parent: '130000' },
{ label: '秦皇岛市', value: '130300', parent: '130000' },
{ label: '上海市', value: '310100', parent: '310000' },
{ label: '东城区', value: '110101', parent: '110100' },
{ label: '西城区', value: '110102', parent: '110100' },
{ label: '朝阳区', value: '110105', parent: '110100' },
{ label: '和平区', value: '120101', parent: '120000' },
{ label: '河东区', value: '120102', parent: '120000' },
{ label: '河西区', value: '120103', parent: '120000' },
{ label: '黄浦区', value: '310101', parent: '310100' },
{ label: '徐汇区', value: '310104', parent: '310100' },
{ label: '长宁区', value: '310105', parent: '310100' },
{ label: '长安区', value: '130102', parent: '130100' },
{ label: '桥西区', value: '130104', parent: '130100' },
{ label: '新华区', value: '130105', parent: '130100' },
{ label: '路南区', value: '130202', parent: '130200' },
{ label: '路北区', value: '130203', parent: '130200' },
{ label: '古冶区', value: '130204', parent: '130200' },
{ label: '海港区', value: '130302', parent: '130300' },
{ label: '山海关区', value: '130303', parent: '130300' },
{ label: '北戴河区', value: '130304', parent: '130300' },
]
}
},
mounted() {
// 初始化数据
this.columns[0].options = this.request(null)
},
methods: {
request(parentId) {
return this.mockData.filter(i => i.parent === parentId)
},
/** 当选项被改变时,联动其他组件 */
handleValueChange(event) {
const { type, row, column, value, target } = event
if (type === FormTypes.select) {
// 第一列
if (column.key === 's1') {
// 设置第二列的 options
this.columns[1].options = this.request(value)
// 清空后两列的数据
target.setValues([{
rowKey: row.id,
values: { s2: '', s3: '' }
}])
this.columns[2].options = []
} else
// 第二列
if (column.key === 's2') {
this.columns[2].options = this.request(value)
target.setValues([{
rowKey: row.id,
values: { s3: '' }
}])
}
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -486,7 +486,7 @@
days = this.result.day.cronLastSpecificDomDay + 'L';
break;
case '9':
days = 'L-' + this.day.cronDaysBeforeEomMinus;
days = 'L-' + this.result.day.cronDaysBeforeEomMinus;
break;
case '10':
days = this.result.day.cronDaysNearestWeekday+"W";

View File

@ -0,0 +1,435 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :md="6" :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-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">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button @click="doCgformButton" type="primary" icon="highlight" 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-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
删除
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
已选择
<a style="font-weight: 600">{{ selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<template slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">更多
<a-icon type="down"/>
</a>
<a-menu slot="overlay">
<a-menu-item v-if="record.isDbSynch!='Y'">
<a @click="openSyncModal(record.id)">同步数据库</a>
</a-menu-item>
<template v-if="record.isDbSynch=='Y' && record.tableType !== 3">
<a-menu-item>
<a @click="goPageOnline(record)">功能测试</a>
</a-menu-item>
<a-menu-item>
<a @click="handleOnlineUrlShow(record)">配置地址</a>
</a-menu-item>
</template>
<a-menu-item>
<a @click="handleRemoveRecord(record.id)">移除</a>
</a-menu-item>
<a-menu-item>
<a @click="handleDelete(record.id)">删除</a>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<template slot="dbsync" slot-scope="text">
<span v-if="text==='Y'" style="color:limegreen">已同步</span>
<span v-if="text==='N'" style="color:red">未同步</span>
</template>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<onl-cgform-head-modal ref="modalForm" @ok="modalFormOk"></onl-cgform-head-modal>
<!-- 同步数据库提示框 -->
<a-modal
:width="500"
:height="300"
title="同步数据库"
:visible="syncModalVisible"
@cancel="handleCancleDbSync"
style="top:5%;height: 95%;">
<template slot="footer">
<a-button @click="handleCancleDbSync">关闭</a-button>
<a-button type="primary" :loading="syncLoading" @click="handleDbSync">
确定
</a-button>
</template>
<a-radio-group v-model="synMethod">
<a-radio style="display: block;width: 30px;height: 30px" value="normal">普通同步(保留表数据)</a-radio>
<a-radio style="display: block;width: 30px;height: 30px" value="force">强制同步(删除表,重新生成)</a-radio>
</a-radio-group>
</a-modal>
<!-- 提示online报表链接 -->
<a-modal
:title="onlineUrlTitle"
:visible="onlineUrlVisible"
@cancel="handleOnlineUrlClose">
<template slot="footer">
<a-button @click="handleOnlineUrlClose">关闭</a-button>
<a-button type="primary" class="copy-this-text" :data-clipboard-text="onlineUrl" @click="onCopyUrl">复制</a-button>
</template>
<p>{{ onlineUrl }}</p>
</a-modal>
<enhance-js ref="ehjs"></enhance-js>
<enhance-sql ref="ehsql"></enhance-sql>
<enhance-java ref="ehjava"></enhance-java>
<trans-db2-online ref="transd2o" @ok="transOk"></trans-db2-online>
<code-generator ref="cg"></code-generator>
<onl-cgform-button-list ref="btnList"></onl-cgform-button-list>
</a-card>
</template>
<script>
import { initDictOptions, filterDictText } from '@/components/dict/JDictSelectUtil'
import { deleteAction, postAction } from '@/api/manage'
import JDictSelectTag from '../../../../components/dict/JDictSelectTag.vue'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Clipboard from 'clipboard'
export default {
name: 'OnlCgformHeadList',
mixins: [JeecgListMixin],
components: {
JDictSelectTag,
},
data() {
return {
description: 'Online表单开发管理页面',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function(t, r, index) {
return parseInt(index) + 1
}
},
{
title: '表类型',
align: 'center',
dataIndex: 'tableType',
customRender: (text) => {
return filterDictText(this.tableTypeDictOptions, `${text}`)
}
},
{
title: '表名',
align: 'center',
dataIndex: 'tableName'
},
{
title: '表描述',
align: 'center',
dataIndex: 'tableTxt'
},
{
title: '版本',
align: 'center',
dataIndex: 'tableVersion'
},
{
title: '同步数据库状态',
align: 'center',
dataIndex: 'isDbSynch',
scopedSlots: { customRender: 'dbsync' }
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
],
url: {
list: '/online/cgform/head/list',
delete: '/online/cgform/head/delete',
deleteBatch: '/online/cgform/head/deleteBatch',
doDbSynch: '/online/cgform/api/doDbSynch/',
removeRecord: '/online/cgform/head/removeRecord'
},
tableTypeDictOptions: [],
sexDictOptions: [],
syncModalVisible: false,
syncFormId: '',
synMethod: 'normal',
syncLoading: false,
onlineUrlTitle: '',
onlineUrlVisible: false,
onlineUrl: '',
selectedRowKeys: [],
selectedRows: []
}
},
created() {
//初始化字典 - 表类型
initDictOptions('cgform_table_type').then((res) => {
if (res.success) {
this.tableTypeDictOptions = res.result
}
})
this.loadData()
},
methods: {
doDbSynch(id) {
postAction(this.url.doDbSynch + id, { synMethod: '1' }).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.loadData()
} else {
this.$message.warning(res.message)
}
})
},
handleCancleDbSync() {
this.syncModalVisible = false
},
handleDbSync() {
this.syncLoading = true
postAction(this.url.doDbSynch + this.syncFormId + '/' + this.synMethod).then((res) => {
this.syncModalVisible = false
this.syncLoading = false
if (res.success) {
this.$message.success(res.message)
this.loadData()
} else {
this.$message.warning(res.message)
}
})
},
openSyncModal(id) {
this.syncModalVisible = true
this.syncFormId = id
},
goPageOnline(rd) {
if(rd.isTree=='Y'){
this.$router.push({ path: '/online/cgformTreeList/' + rd.id })
}else{
this.$router.push({ path: '/online/cgformList/' + rd.id })
}
},
handleOnlineUrlClose() {
this.onlineUrlTitle = ''
this.onlineUrlVisible = false
},
handleOnlineUrlShow(record) {
if(record.isTree=='Y'){
this.onlineUrl = `/online/cgformTreeList/${record.id}`
}else{
this.onlineUrl = `/online/cgformList/${record.id}`
}
this.onlineUrlVisible = true
this.onlineUrlTitle = '菜单链接[' + record.tableTxt + ']'
},
handleRemoveRecord(id) {
let that = this
this.$confirm({
title: '确认要移除此记录?',
onOk() {
deleteAction(that.url.removeRecord, { id: id }).then((res) => {
if (res.success) {
that.$message.success('移除成功')
that.loadData()
} else {
that.$message.warning(res.message)
}
})
},
onCancel() {
}
})
},
doEnhanceJs() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
this.$refs.ehjs.show(this.selectedRowKeys[0])
},
doEnhanceSql() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
this.$refs.ehsql.show(this.selectedRowKeys[0])
},
doEnhanceJava() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
this.$refs.ehjava.show(this.selectedRowKeys[0])
},
doCgformButton() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
this.$refs.btnList.show(this.selectedRowKeys[0])
//this.$router.push({ path: '/online/cgformButton/' + this.selectedRowKeys[0] })
},
importOnlineForm() {
this.$refs.transd2o.show()
},
transOk() {
this.loadData()
},
goGenerateCode() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
let row = this.selectedRows[0]
if (!row.isDbSynch || row.isDbSynch == 'N') {
this.$message.warning('请先同步数据库!')
return
}
if (row.tableType == 3) {
this.$message.warning('请选中该表对应的主表生成代码')
return
}
this.$refs.cg.show(this.selectedRowKeys[0])
},
onSelectChange(keys, rows) {
this.selectedRowKeys = keys
this.selectedRows = rows
},
onCopyUrl(){
var clipboard = new Clipboard('.copy-this-text')
clipboard.on('success', () => {
clipboard.destroy()
this.$message.success('复制成功')
this.handleOnlineUrlClose()
})
clipboard.on('error', () => {
this.$message.error('该浏览器不支持自动复制')
clipboard.destroy()
})
}
}
}
</script>
<style lang="less">
.ant-card-body .table-operator {
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
.valid-error-cust{
.ant-select-selection{
border:2px solid #f5222d;
}
}
</style>

View File

@ -0,0 +1,619 @@
<template>
<a-card :bordered="false" style="height: 100%">
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24" v-if="queryInfo && queryInfo.length>0">
<template v-for="(item,index) in queryInfo">
<template v-if=" item.hidden==='1' ">
<a-col v-if="item.view=='datetime'" :md="12" :sm="16" :key=" 'query'+index " v-show="toggleSearchStatus">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
<a-col v-else :md="6" :sm="8" :key=" 'query'+index " v-show="toggleSearchStatus">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
</template>
<template v-else>
<a-col v-if="item.view=='datetime'" :md="12" :sm="16" :key=" 'query'+index ">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
<a-col v-else :md="6" :sm="8" :key=" 'query'+index ">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
</template>
</template>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchByquery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button v-if="buttonSwitch.add" @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button v-if="buttonSwitch.import" @click="handleImportXls" type="primary" icon="upload" style="margin-left:8px">导入</a-button>
<a-button v-if="buttonSwitch.export" @click="handleExportXls" type="primary" icon="download" style="margin-left:8px">导出</a-button>
<template v-if="cgButtonList && cgButtonList.length>0" v-for="(item,index) in cgButtonList">
<a-button
v-if=" item.optType=='js' "
:key=" 'cgbtn'+index "
@click="cgButtonJsHandler(item.buttonCode)"
type="primary"
:icon="item.buttonIcon"
style="margin-left:8px">
{{ item.buttonName }}
</a-button>
<a-button
v-else-if=" item.optType=='action' "
:key=" 'cgbtn'+index "
@click="cgButtonActionHandler(item.buttonCode)"
type="primary"
:icon="item.buttonIcon"
style="margin-left:8px">
{{ item.buttonName }}
</a-button>
</template>
<a-button
v-if="buttonSwitch.batch_delete"
@click="handleDelBatch"
style="margin-left:8px"
v-show="table.selectedRowKeys.length > 0"
ghost
type="primary"
icon="delete">批量删除</a-button>
</div>
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
已选择&nbsp;<a style="font-weight: 600">{{ table.selectedRowKeys.length }}</a>项&nbsp;&nbsp;
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="cgformAutoList"
bordered
size="middle"
rowKey="id"
:columns="table.columns"
:dataSource="table.dataSource"
:pagination="table.pagination"
:loading="table.loading"
:rowSelection="{selectedRowKeys:table.selectedRowKeys, onChange: handleChangeInTableSelect}"
@change="handleTableChange"
style="min-height: 300px">
<template slot="dateSlot" slot-scope="text">
<span>{{ getFormatDate(text) }}</span>
</template>
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无此图片</span>
<img v-else :src="getImgView(text)" height="25px" alt="图片不存在" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无此文件</span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="uploadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<template v-if="hasBpmStatus">
<template v-if="record.bpm_status == '1'||record.bpm_status == ''|| record.bpm_status == null">
<template v-if="buttonSwitch.update">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
</template>
</template>
</template>
<template v-else>
<template v-if="buttonSwitch.update">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
</template>
</template>
<a-dropdown>
<a class="ant-dropdown-link">
更多 <a-icon type="down" />
</a>
<a-menu slot="overlay">
<a-menu-item >
<a href="javascript:;" @click="handleDetail(record)">详情</a>
</a-menu-item>
<template v-if="hasBpmStatus">
</template>
<template v-else>
<a-menu-item v-if="buttonSwitch.delete">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</template>
<template v-if="cgButtonLinkList && cgButtonLinkList.length>0" v-for="(btnItem,btnIndex) in cgButtonLinkList">
<a-menu-item :key=" 'cgbtnLink'+btnIndex ">
<a href="javascript:void(0);" @click="cgButtonLinkHandler(record,btnItem.buttonCode,btnItem.optType)">
<a-icon v-if="btnItem.buttonIcon" :type="btnItem.buttonIcon" />
{{ btnItem.buttonName }}
</a>
</a-menu-item>
</template>
</a-menu>
</a-dropdown>
</span>
</a-table>
<OnlCgformAutoModal @success="handleFormSuccess" ref="modal" :code="code"></OnlCgformAutoModal>
<j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal>
</div>
</a-card>
</template>
<script>
import { postAction,getAction,deleteAction,downFile } from '@/api/manage'
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import { filterObj } from '@/utils/util';
import JImportModal from '@/components/jeecg/JImportModal'
export default {
name: 'OnlCgFormAutoList',
components: {
JImportModal
},
data() {
return {
code: '',
description: '在线报表功能测试页面',
currentTableName:"",
url: {
getQueryInfo:'/online/cgform/api/getQueryInfo/',
getColumns: '/online/cgform/api/getColumns/',
getData: '/online/cgform/api/getData/',
optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton',
},
flowCodePre:"onl_",
isorter:{
column: 'createTime',
order: 'desc',
},
//dictOptions:{fieldName:[]}
dictOptions:{
},
cgButtonLinkList:[],
cgButtonList:[],
queryInfo:[],
queryParam:{
},
toggleSearchStatus:false,
table: {
loading: true,
// 表头
columns: [],
//数据集
dataSource: [],
// 选择器
selectedRowKeys: [],
selectionRows: [],
// 分页参数
pagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
}
},
actionColumn:{
title: '操作',
dataIndex: 'action',
scopedSlots: { customRender: 'action' },
fixed:"right",
align:"center",
width:150
},
formTemplate:"99",
EnhanceJS:'',
hideColumns:[],
buttonSwitch:{
add:true,
update:true,
delete:true,
batch_delete:true,
import:true,
export:true
},
hasBpmStatus:false,
}
},
created() {
this.initAutoList();
},
mounted(){
this.cgButtonJsHandler('mounted')
},
watch: {
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initAutoList()
}
},
methods: {
hasBpmStatusFilter(){
var columnObjs = this.table.columns;
let columns = [];
for (var item of columnObjs) {
columns.push(item.dataIndex);
}
if(columns.includes('bpm_status')||columns.includes('BPM_STATUS')){
this.hasBpmStatus = true;
}else{
this.hasBpmStatus = false;
}
},
initQueryInfo(){
getAction(`${this.url.getQueryInfo}${this.code}`).then((res)=>{
console.log("--onlineList-获取查询条件配置",res);
if(res.success){
this.queryInfo = res.result
}else{
this.$message.warning(res.message)
}
})
},
initAutoList(){
if(!this.$route.params.code){
return false
}
this.table.loading = true
this.code = this.$route.params.code
getAction(`${this.url.getColumns}${this.code}`).then((res)=>{
console.log("--onlineList-加载动态列>>",res);
if(res.success){
this.dictOptions = res.result.dictOptions
this.formTemplate = res.result.formTemplate
this.description = res.result.description
this.currentTableName = res.result.currentTableName
this.initCgButtonList(res.result.cgButtonList)
this.initCgEnhanceJs(res.result.enhanceJs)
this.initButtonSwitch(res.result.hideColumns)
let currColumns = res.result.columns
for(let a=0;a<currColumns.length;a++){
if(currColumns[a].customRender){
let dictCode = currColumns[a].customRender;
currColumns[a].customRender=(text)=>{
return filterMultiDictText(this.dictOptions[dictCode], text);
}
}
}
currColumns.push(this.actionColumn);
this.table.columns = [...currColumns]
this.hasBpmStatusFilter();
this.loadData();
this.initQueryInfo();
}else{
this.$message.warning(res.message)
}
})
},
loadData(arg){
if(arg==1){
this.table.pagination.current=1
}
let params = this.getQueryParams();//查询条件
console.log("--onlineList-查询条件-->",params)
getAction(`${this.url.getData}${this.code}`,params).then((res)=>{
console.log("--onlineList-列表数据",res)
if(res.success){
let result = res.result;
if(Number(result.total)>0){
this.table.pagination.total = Number(result.total)
this.table.dataSource = result.records
}else{
this.table.pagination.total=0;
this.table.dataSource=[]
//this.$message.warning("查无数据")
}
}else{
this.$message.warning(res.message)
}
this.table.loading = false
})
},
getQueryParams() {
let param = Object.assign({}, this.queryParam,this.isorter);
param.pageNo = this.table.pagination.current;
param.pageSize = this.table.pagination.pageSize;
return filterObj(param);
},
handleChangeInTableSelect(selectedRowKeys, selectionRows) {
this.table.selectedRowKeys = selectedRowKeys
this.table.selectionRows = selectionRows
},
handleTableChange(pagination, filters, sorter){
//TODO 筛选
if (Object.keys(sorter).length>0){
this.isorter.column = sorter.field;
this.isorter.order = "ascend"==sorter.order?"asc":"desc"
}
this.table.pagination = pagination;
this.loadData();
},
handleAdd(){
this.cgButtonJsHandler('beforeAdd')
this.$refs.modal.add(this.formTemplate);
},
handleImportXls(){
this.$refs.importModal.show()
},
importOk(){
this.loadData(1)
},
handleExportXls2(){
let param = this.queryParam;
if(this.table.selectedRowKeys && this.table.selectedRowKeys.length>0){
param['selections'] = this.table.selectedRowKeys.join(",")
}
let paramsStr = encodeURI(JSON.stringify(param));
console.log('paramsStr: ' + paramsStr)
let url = window._CONFIG['domianURL']+this.url.exportXls+this.code+"?paramsStr="+paramsStr
window.location.href = url;
},
handleExportXls(){
let param = this.queryParam;
if(this.table.selectedRowKeys && this.table.selectedRowKeys.length>0){
param['selections'] = this.table.selectedRowKeys.join(",")
}
console.log("导出参数",param)
let paramsStr = JSON.stringify(filterObj(param));
downFile(this.url.exportXls+this.code,{paramsStr:paramsStr}).then((data)=>{
if (!data) {
this.$message.warning("文件下载失败")
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), this.description+'.xls')
}else{
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', this.description+'.xls')
document.body.appendChild(link)
link.click()
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
})
},
handleEdit(record){
this.cgButtonLinkHandler(record,"beforeEdit","js")
this.$refs.modal.edit(this.formTemplate,record.id);
},
handleDetail(record){
this.$refs.modal.detail(this.formTemplate,record.id);
},
handleDeleteOne(record){
this.cgButtonLinkHandler(record,"beforeDelete","js")
this.handleDelete(record.id)
},
handleDelete(id){
deleteAction(this.url.optPre+this.code+"/"+id).then((res)=>{
if(res.success){
this.$message.success(res.message)
this.loadData()
}else{
this.$message.warning(res.message)
}
})
},
handleFormSuccess(){
this.loadData()
},
onClearSelected(){
this.table.selectedRowKeys = []
this.table.selectionRows = []
},
getImgView(text){
if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
return window._CONFIG['imgDomainURL']+"/"+text
},
uploadFile(text){
if(!text){
this.$message.warning("未知的文件")
return;
}
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['imgDomainURL']+"/"+text);//TODO 下载的方法
},
handleDelBatch(){
if(this.table.selectedRowKeys.length<=0){
this.$message.warning('请选择一条记录!');
return false;
}else{
let ids = "";
let that = this;
that.table.selectedRowKeys.forEach(function(val) {
ids+=val+",";
});
that.$confirm({
title:"确认删除",
content:"是否删除选中数据?",
onOk: function(){
that.handleDelete(ids)
that.onClearSelected();
}
});
}
},
searchByquery(){
this.loadData(1);
},
searchReset(){
this.queryParam = {}
this.loadData(1);
},
handleToggleSearch(){
this.toggleSearchStatus = !this.toggleSearchStatus;
},
getFormatDate(text){
if(!text){
return ''
}
let a = text;
if(a.length>10){
a = a.substring(0,10);
}
return a;
},
getImportUrl(){
return '/online/cgform/api/importXls/'+this.code
},
initCgEnhanceJs(enhanceJs){
//console.log("--onlineList-js增强",enhanceJs)
if(enhanceJs){
let Obj = eval ("(" + enhanceJs + ")");
this.EnhanceJS = new Obj(getAction,postAction,deleteAction);
this.cgButtonJsHandler('created')
}else{
this.EnhanceJS = ''
}
},
initCgButtonList(btnList){
let linkArr = []
let buttonArr = []
if(btnList && btnList.length>0){
for(let i=0;i<btnList.length;i++){
let temp = btnList[i]
if(temp.buttonStyle=='button'){
buttonArr.push(temp)
}else if(temp.buttonStyle=='link'){
linkArr.push(temp)
}
}
}
this.cgButtonLinkList = [...linkArr]
this.cgButtonList=[...buttonArr]
},
cgButtonJsHandler(buttonCode){
if(this.EnhanceJS[buttonCode]){
this.EnhanceJS[buttonCode](this)
}
},
cgButtonActionHandler(buttonCode){
//处理自定义button的 需要配置该button自定义sql
if(!this.table.selectedRowKeys || this.table.selectedRowKeys.length==0){
this.$message.warning("请先选中一条记录")
return false
}
if(this.table.selectedRowKeys.length>1){
this.$message.warning("请只选中一条记录")
return false
}
let params = {
formId:this.code,
buttonCode:buttonCode,
dataId:this.table.selectedRowKeys[0]
}
console.log("自定义按钮请求后台参数",params)
postAction(this.url.buttonAction,params).then(res=>{
if(res.success){
this.loadData()
this.$message.success("处理完成!")
}else{
this.$message.warning("处理失败!")
}
})
},
cgButtonLinkHandler(record,buttonCode,optType){
if(optType=="js"){
if(this.EnhanceJS[buttonCode]){
this.EnhanceJS[buttonCode](this,record)
}
}else if(optType=="action"){
let params = {
formId:this.code,
buttonCode:buttonCode,
dataId:record.id
}
console.log("自定义按钮link请求后台参数",params)
postAction(this.url.buttonAction,params).then(res=>{
if(res.success){
this.loadData()
this.$message.success("处理完成!")
}else{
this.$message.warning("处理失败!")
}
})
}
},
initButtonSwitch(hideColumns){
if(hideColumns && hideColumns.length>0){
Object.keys(this.buttonSwitch).forEach(key=>{
if(hideColumns.indexOf(key)>=0){
this.buttonSwitch[key]=false
}
})
}
}
}
}
</script>
<style>
.ant-card-body .table-operator{
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td{
padding-top:15px;
padding-bottom:15px;
}
.anty-row-operator button{margin: 0 5px}
.ant-btn-danger{background-color: #ffffff}
.anty-img-wrap{height:25px;position: relative;}
.anty-img-wrap > img{max-height:100%;}
.ant-modal-cust-warp{height: 100%}
.ant-modal-cust-warp .ant-modal-body{height:calc(100% - 110px) !important;overflow-y: auto}
.ant-modal-cust-warp .ant-modal-content{height:90% !important;overflow-y: hidden}
</style>

View File

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

View File

@ -0,0 +1,268 @@
/**
* 同步列表,可以同步新增、修改、删除
* @author sunjianlei
* */
export function syncAllTable(vm, table1) {
vm.$refs.editableTable.resetScrollTop()
let deleteIds = table1.$refs.editableTable.getDeleteIds()
let table1Value
table1.$refs.editableTable.getValuesPromise(false).then((values) => {
table1Value = values
return vm.$refs.editableTable.getValuesPromise(false)
}).then((values) => {
table1Value.forEach(value => {
let flag = false
values.forEach((thisValue) => {
if (value.id === thisValue.id) {
// 判断是否修改了值
let dbFieldName = thisValue['dbFieldName']
let dbFieldTxt = thisValue['dbFieldTxt']
// return
if (value.dbFieldName !== dbFieldName
|| value.dbFieldTxt !== dbFieldTxt) {
// 修改了
vm.$refs.editableTable.setValues([{
rowKey: thisValue.id,
values: {
dbFieldName: value.dbFieldName,
dbFieldTxt: value.dbFieldTxt
}
}])
}
flag = true
} else {
// id不匹配则有可能是新增也有可能是删除了的
// 遍历传进来的 deleteIds 进行对比
deleteIds.forEach(delId => {
// 对比成功,则删除该条数据
if (delId === thisValue.id) {
vm.$refs.editableTable.removeRows(vm.$refs.editableTable.caseId + delId)
flag = true
}
})
}
})
// return
// 判断是否操作了该条数据,若没有操作则代表要执行新增操作
if (!flag) {
let record = Object.assign({}, value)
vm.columns.forEach(column => {
if (
column.dataIndex !== 'dbFieldName' &&
column.dataIndex !== 'dbFieldTxt'
) {
record[column.dataIndex] = column.defaultValue
}
})
vm.$refs.editableTable.push(record)
}
})
})
}
/**
* 将数据分类并Set进dataSource
* @author sunjianlei
**/
export function setDataSource(vm, queryData) {
let dataSource = []
// 遍历查询出来的数据
queryData.forEach(value => {
let data = { id: value['id'] }
vm.columns.forEach(column => {
let key = column.key
if (key) {
data[key] = value[key]
// 由于多选下拉框返回的是一个数组,所以需要改成 [1,2,3] 数组的形式,否则组件不识别
// if (key === 'indexField') {
// data[key] = value[key].split(',')
// }
}
})
dataSource.push(data)
})
vm.dataSource = dataSource
}
/** 获取主表的初始化数据 */
export function getMasterTableInitialData() {
return [
{
dbFieldName: 'id',
dbFieldTxt: '主键',
dbLength: 36,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '1',
dbIsNull: '0',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 1
},
{
dbFieldName: 'create_by',
dbFieldTxt: '创建人',
dbLength: 50,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 2
},
{
dbFieldName: 'create_time',
dbFieldTxt: '创建日期',
dbLength: 20,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'Date',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'datetime',
fieldLength: '120',
queryMode: 'single',
orderNum: 3
},
{
dbFieldName: 'update_by',
dbFieldTxt: '更新人',
dbLength: 50,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 4
},
{
dbFieldName: 'update_time',
dbFieldTxt: '更新日期',
dbLength: 20,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'Date',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'datetime',
fieldLength: '120',
queryMode: 'single',
orderNum: 5
},{
dbFieldName: 'sys_org_code',
dbFieldTxt: '所属部门',
dbLength: 64,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 6
}
// {
// dbFieldName: 'sys_org_code',
// dbFieldTxt: '所属部门',
// dbLength: 50,
// dbPointLength: 0,
// dbDefaultVal: '',
// dbType: 'string',
// dbIsKey: false,
// dbIsNull: true
// }, {
// dbFieldName: 'sys_company_code',
// dbFieldTxt: '所属公司',
// dbLength: 50,
// dbPointLength: 0,
// dbDefaultVal: '',
// dbType: 'string',
// dbIsKey: false,
// dbIsNull: true
// }, {
// dbFieldName: 'bpm_status',
// dbFieldTxt: '流程状态',
// dbLength: 32,
// dbPointLength: 0,
// dbDefaultVal: '',
// dbType: 'string',
// dbIsKey: false,
// dbIsNull: true
// }
]
}
/** 获取树的初始化数据 */
export function getTreeNeedFields() {
return [{
dbFieldName: 'pid',
dbFieldTxt: '父级节点',
dbLength: 32,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '1',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 7
},{
dbFieldName: 'has_child',
dbFieldTxt: '是否有子节点',
dbLength: 3,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'list',
fieldLength: '120',
queryMode: 'single',
orderNum: 8,
// table3
dictField:"yn"
}]
}

View File

@ -205,11 +205,11 @@
mobile: {rules: [{validator: this.validateMobile}]}
},
url: {
delete: '/sysdepart/sysDepart/delete',
edit: '/sysdepart/sysDepart/edit',
deleteBatch: '/sysdepart/sysDepart/deleteBatch',
exportXlsUrl: "sysdepart/sysDepart/exportXls",
importExcelUrl: "sysdepart/sysDepart/importExcel",
delete: '/sys/sysDepart/delete',
edit: '/sys/sysDepart/edit',
deleteBatch: '/sys/sysDepart/deleteBatch',
exportXlsUrl: "sys/sysDepart/exportXls",
importExcelUrl: "sys/sysDepart/importExcel",
},
}
},
@ -292,7 +292,7 @@
var that = this
this.$confirm({
title: '确认删除',
content: '确定要删除所选中的 ' + this.checkedKeys.length + ' 条数据?',
content: '确定要删除所选中的 ' + this.checkedKeys.length + ' 条数据,以及子节点数据吗?',
onOk: function () {
deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
if (res.success) {

View File

@ -148,9 +148,9 @@
selectedRowKeys: [],
selectedRows: [],
url: {
list: "/sysdepart/sysDepart/list",
delete: "/sysdepart/sysDepart/delete",
deleteBatch: "/sysdepart/sysDepart/deleteBatch",
list: "/sys/sysDepart/list",
delete: "/sys/sysDepart/delete",
deleteBatch: "/sys/sysDepart/deleteBatch",
},
}

View File

@ -19,7 +19,7 @@
</a-form-item>
</a-col>
<a-col :md="8" :sm="10">
<a-col :md="6" :sm="10">
<a-form-item label="创建时间" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-range-picker
style="width: 210px"
@ -31,14 +31,19 @@
/>
</a-form-item>
</a-col>
<a-col :md="8" :sm="10" >
<span style="float: right;" class="table-page-search-submitButtons">
<a-button type="primary" style="left: -35px" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px;left: -35px">重置</a-button>
</span>
<a-col :md="5" :sm="8" v-if="tabKey === '2'">
<a-form-item label="操作类型" style="left: 10px">
<j-dict-select-tag v-model="queryParam.operateType" placeholder="请选择操作类型" dictCode="operate_type"/>
</a-form-item>
</a-col>
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-col :md="6" :sm="24" >
<a-button type="primary" style="left: 10px" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px;left: 10px">重置</a-button>
</a-col>
</span>
</a-row>
</a-form>
</div>
@ -58,7 +63,10 @@
<div style="margin-bottom: 5px"><a-badge status="success" style="vertical-align: middle;"/><span style="vertical-align: middle;">请求方法:{{ record.method }}</span></div>
<div><a-badge status="processing" style="vertical-align: middle;"/><span style="vertical-align: middle;">请求参数:{{ record.requestParam }}</span></div>
</div>
<!-- 字符串超长截取省略号显示-->
<span slot="logContent" slot-scope="text, record">
<j-ellipsis :value="text" :length="40"/>
</span>
</a-table>
<!-- table区域-end -->
</a-card>
@ -67,10 +75,14 @@
<script>
import { filterObj } from '@/utils/util';
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import JEllipsis from '@/components/jeecg/JEllipsis'
export default {
name: "LogList",
mixins:[JeecgListMixin],
components: {
JEllipsis
},
data () {
return {
description: '这是日志管理页面',
@ -81,6 +93,7 @@
logType:'1',
keyWord:'',
},
tabKey: "1",
// 表头
columns: [
{
@ -96,6 +109,7 @@
title: '日志内容',
align:"left",
dataIndex: 'logContent',
scopedSlots: { customRender: 'logContent' },
sorter: true
},
{
@ -143,6 +157,12 @@
sorter: true
}
],
operateColumn:
{
title: '操作类型',
dataIndex: 'operateType_dictText',
align:"center",
},
labelCol: {
xs: { span: 1 },
sm: { span: 2 },
@ -177,6 +197,17 @@
},
// 日志类型
callback(key){
// 动态添加操作类型列
if (key == 2) {
this.tabKey = '2';
this.columns.splice(7, 0, this.operateColumn);
}else if(this.columns.length == 9)
{
this.tabKey = '1';
this.columns.splice(7,1);
}
let that=this;
that.queryParam.logType=key;
that.loadData();

View File

@ -98,7 +98,7 @@
} else if (text == 1) {
return '菜单'
} else if (text == 2) {
return '按钮'
return '按钮/权限'
} else {
return text
}

View File

@ -68,13 +68,13 @@
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a v-if="record.sendStatus == 0" @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
<a-divider type="vertical" v-if="record.sendStatus == 0"/>
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
<a-menu slot="overlay">
<a-menu-item>
<a-menu-item v-if="record.sendStatus != 1">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>

View File

@ -125,9 +125,9 @@
scopedSlots: { customRender: 'action' },
}],
url: {
list: "/system/sysAnnouncementSend/getMyAnnouncementSend",
editCementSend:"system/sysAnnouncementSend/editByAnntIdAndUserId",
readAllMsg:"system/sysAnnouncementSend/readAll",
list: "/sys/sysAnnouncementSend/getMyAnnouncementSend",
editCementSend:"sys/sysAnnouncementSend/editByAnntIdAndUserId",
readAllMsg:"sys/sysAnnouncementSend/readAll",
},
loading:false,
}

View File

@ -3,7 +3,7 @@
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-form layout="inline" @submit.prevent="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="12">
@ -117,8 +117,9 @@
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
<a @click="handleEdit(record)" v-has="'user:edit'">编辑</a>
<a-divider type="vertical" v-has="'user:edit'"/>
<a-dropdown>
<a class="ant-dropdown-link">
@ -140,13 +141,13 @@
</a-menu-item>
<a-menu-item v-if="record.status==1">
<a-popconfirm title="确定冻结吗?" @confirm="() => handleFrozen(record.id,2)">
<a-popconfirm title="确定冻结吗?" @confirm="() => handleFrozen(record.id,2,record.username)">
<a>冻结</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item v-if="record.status==2">
<a-popconfirm title="确定解冻吗?" @confirm="() => handleFrozen(record.id,1)">
<a-popconfirm title="确定解冻吗?" @confirm="() => handleFrozen(record.id,1,record.username)">
<a>解冻</a>
</a-popconfirm>
</a-menu-item>
@ -297,6 +298,16 @@
} else {
let ids = "";
let that = this;
let isAdmin = false;
that.selectionRows.forEach(function (row) {
if (row.username == 'admin') {
isAdmin = true;
}
});
if (isAdmin) {
that.$message.warning('管理员账号不允许此操作,请重新选择!');
return;
}
that.selectedRowKeys.forEach(function (val) {
ids += val + ",";
});
@ -326,8 +337,13 @@
this.batchFrozen(1);
}
},
handleFrozen: function (id, status) {
handleFrozen: function (id, status, username) {
let that = this;
//TODO 后台校验管理员角色
if ('admin' == username) {
that.$message.warning('管理员账号不允许此操作!');
return;
}
frozenBatch({ids: id, status: status}).then((res) => {
if (res.success) {
that.$message.success(res.message);

View File

@ -105,7 +105,7 @@
mobile:{rules: [{validator:this.validateMobile}]}
},
url: {
add: "/sysdepart/sysDepart/add",
add: "/sys/sysDepart/add",
},
}
},

View File

@ -213,7 +213,7 @@
component:{rules: [{ required: this.show, message: '请输入前端组件!' }]},
url:{rules: [{ required: this.show, message: '请输入菜单路径!' }]},
permsType:{rules: [{ required: true, message: '请输入授权策略!' }]},
sortNo:{rules: [{initialValue:1.0,validator: this.validateNumber}]},
sortNo:{initialValue:1.0,rules: [{validator: this.validateNumber}]},
}
}
},

View File

@ -8,7 +8,7 @@
@cancel="handleCancel"
okText="保存并安排任务"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
@ -23,11 +23,12 @@
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="cron表达式">
<a-input placeholder="请输入cron表达式" v-decorator="['cronExpression', {'initialValue':'0/1 * * * * ?',rules: [{ required: true, message: '请输入任务类名!' }]}]" />
<a target="_blank" href="http://cron.qqe2.com/">
<a-icon type="share-alt" />
在线cron表达式生成
</a>
<!-- <a-input placeholder="请输入cron表达式" v-decorator="['cronExpression', {'initialValue':'0/1 * * * * ?',rules: [{ required: true, message: '请输入任务类名!' }]}]" />-->
<!-- <a target="_blank" href="http://cron.qqe2.com/">-->
<!-- <a-icon type="share-alt" />-->
<!-- 在线cron表达式生成-->
<!-- </a>-->
<j-cron ref="innerVueCron" v-decorator="['cronExpression', {'initialValue':'0/1 * * * * ?',rules: [{ required: true, message: '请输入cron表达式!' }]}]" @change="setCorn"></j-cron>
</a-form-item>
<a-form-item
:labelCol="labelCol"
@ -52,7 +53,7 @@
<a-radio-button :value="-1">停止</a-radio-button>
</a-radio-group>
</a-form-item>
</a-form>
</a-spin>
</a-modal>
@ -60,11 +61,15 @@
<script>
import { httpAction } from '@/api/manage'
import JCron from "@/components/jeecg/JCron.vue";
import pick from 'lodash.pick'
import moment from "moment"
export default {
name: "QuartzJobModal",
components: {
JCron
},
data () {
return {
title:"操作",
@ -78,10 +83,18 @@
xs: { span: 24 },
sm: { span: 16 },
},
cron: {
label: '',
value: ''
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
validatorRules: {
cron: {
rules: [{
required: true, message: '请输入cron表达式!'
}]
}
},
url: {
add: "/sys/quartzJob/add",
@ -96,8 +109,7 @@
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.model = Object.assign({},record);
console.log(this.model)
this.visible = true;
this.$nextTick(() => {
@ -113,7 +125,13 @@
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
console.log('values',values)
if (!err) {
// if (typeof values.cronExpression == "undefined" || Object.keys(values.cronExpression).length==0 ) {
// this.$message.warning('请输入cron表达式!');
// return false;
// }
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -122,12 +140,12 @@
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
console.log(formData)
console.log('提交参数',formData)
httpAction(httpurl,formData,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
@ -146,7 +164,24 @@
handleCancel () {
this.close()
},
setCorn(data){
console.log('data)',data);
this.$nextTick(() => {
this.model.cronExpression = data;
})
// console.log(Object.keys(data).length==0);
// if (Object.keys(data).length==0) {
// this.$message.warning('请输入cron表达式!');
// }
},
validateCron(rule, value, callback){
if(!value){
callback()
}else if (Object.keys(value).length==0) {
callback("请输入cron表达式!");
}
},
}
}

View File

@ -196,8 +196,12 @@
getQueryParams(){
let param = Object.assign({}, this.queryParam,this.isorter);
param.field = this.getQueryField();
param.current = this.ipagination.current;
//--update-begin----author:scott---date:20190818------for:新建公告时指定特定用户翻页错误SelectUserListModal #379----
// param.current = this.ipagination.current;
// param.pageSize = this.ipagination.pageSize;
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
//--update-end----author:scott---date:20190818------for:新建公告时指定特定用户翻页错误SelectUserListModal #379---
return filterObj(param);
},
getQueryField(){

View File

@ -99,9 +99,9 @@
endTime:{rules: [{ required: true, message: '请输入代理结束时间!' }]},
},
url: {
add: "/system/sysUserAgent/add",
edit: "/system/sysUserAgent/edit",
queryByUserName:"/system/sysUserAgent/queryByUserName",
add: "/sys/sysUserAgent/add",
edit: "/sys/sysUserAgent/edit",
queryByUserName:"/sys/sysUserAgent/queryByUserName",
},
}
},

View File

@ -45,6 +45,7 @@
mode="multiple"
style="width: 100%"
placeholder="请选择用户角色"
optionFilterProp = "children"
v-model="selectedRole">
<a-select-option v-for="(role,roleindex) in roleList" :key="roleindex.toString()" :value="role.id">
{{ role.roleName }}
@ -411,7 +412,7 @@
if(!value){
callback()
}else{
if(new RegExp(/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/).test(value)){
if(new RegExp(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/).test(value)){
var params = {
tableName: 'sys_user',
fieldName: 'email',

View File

@ -1,5 +1,5 @@
<template>
<a-card :bordered="false">
<a-card :bordered="false" style="width: 160%;text-align: center;margin-left:-25%">
<a-steps class="steps" :current="currentTab">
<a-step title="账户信息" />
<a-step title="身份验证" />

View File

@ -85,12 +85,12 @@
<a-form-item>
<a-checkbox v-model="formLogin.rememberMe">自动登陆</a-checkbox>
<router-link :to="{ name: 'alteration'}" class="forge-password" style="float: right;">
<!-- <router-link :to="{ name: 'alteration'}" class="forge-password" style="float: right;">
忘记密码
</router-link>
<router-link :to="{ name: 'register'}" class="forge-password" style="float: right;margin-right: 10px" >
注册账户
</router-link>
</router-link>-->
</a-form-item>
<a-form-item style="margin-top:24px">
@ -176,6 +176,8 @@
import { putAction } from '@/api/manage'
import { postAction } from '@/api/manage'
import { encryption , getEncryptedString } from '@/utils/encryption/aesEncrypt'
import store from '@/store/'
import { USER_INFO } from "@/store/mutation-types"
export default {
components: {
@ -342,7 +344,9 @@
})
},
loginSuccess () {
this.loginBtn = false
// update-begin- author:sunjianlei --- date:20190812 --- for: 登录成功后不解除禁用按钮,防止多次点击
// this.loginBtn = false
// update-end- author:sunjianlei --- date:20190812 --- for: 登录成功后不解除禁用按钮,防止多次点击
this.$router.push({ name: "dashboard" })
this.$notification.success({
message: '欢迎',
@ -425,6 +429,10 @@
}
putAction("/sys/selectDepart",obj).then(res=>{
if(res.success){
const userInfo = res.result.userInfo;
Vue.ls.set(USER_INFO, userInfo, 7 * 24 * 60 * 60 * 1000);
store.commit('SET_INFO', userInfo);
//console.log("---切换组织机构---userInfo-------",store.getters.userInfo.orgCode);
this.departClear()
this.loginSuccess()
}else{

View File

@ -41,7 +41,7 @@
<script>
import JGraphicCode from '@/components/jeecg/JGraphicCode'
import { getAction } from '@/api/manage'
import {duplicateCheck } from '@/api/api'
import {checkOnlyUser } from '@/api/api'
export default {
name: "Step1",
components: {
@ -116,14 +116,12 @@
callback("请输入用户名和手机号");
}
//判断用户输入账号还是手机号码
if(reg.test(value)){
var params = {
tableName: 'sys_user',
fieldName: 'phone',
fieldVal: value,
dataId: null
phone : value,
};
duplicateCheck(params).then((res) => {
checkOnlyUser(params).then((res) => {
if (res.success) {
callback("用户名不存在!")
} else {
@ -132,18 +130,15 @@
})
}else{
var params = {
tableName: 'sys_user',
fieldName: 'username',
fieldVal: value,
dataId: null
username: value,
};
duplicateCheck(params).then((res) => {
checkOnlyUser(params).then((res) => {
if (res.success) {
callback("用户名不存在!")
} else {
callback()
}
})
callback("用户名不存在!")
} else {
callback()
}
})
}
},

View File

@ -30,22 +30,22 @@
</a-input>
</a-form-item>
<a-form-item
label="验证码"
:labelCol="{span: 5}"
:wrapperCol="{span: 19}"
style="margin-left:106px"
v-if="show">
<a-row :gutter="16" >
<a-col class="gutter-row" :span="16">
<a-row :gutter="16" style="margin-left: 35px">
<a-col class="gutter-row" :span="10">
<a-input
v-decorator="['captcha',validatorRules.captcha]"
type="text"
placeholder="请输入验证码" >
placeholder="手机短信验证码" >
</a-input>
</a-col>
<a-col class="gutter-row" :span="8" >
<a-button
class="getCaptcha"
tabindex="-1"
size="default"
:disabled="state.smsSendBtn"
@click.stop.prevent="getCaptcha"
v-text="!state.smsSendBtn && '获取验证码' || (state.time+' s')"></a-button>