You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
680 lines
17 KiB
680 lines
17 KiB
<!--
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-18 11:32:14
|
|
@ 备注: 自定义表单列表
|
|
-->
|
|
<script lang='ts' setup>
|
|
import { ElTable } from 'element-plus'
|
|
|
|
import { attrButton,tableButton,tableButtonList,tableLogButtonList,tableAttrLogButtonList } from '@/api/DesignForm/tableButton'
|
|
|
|
import { json2string,objToStringify,string2json,stringToObj } from '@/utils/DesignForm/form'
|
|
import { analysisForm,setFlowFormKeyPower } from '@/api/workflowapi/index'
|
|
import { gainFormTableField } from '@/api/DesignForm/requestapi'
|
|
import { formTableField,formTabelStruct } from "@/api/DesignForm/type";
|
|
|
|
import tempOtherUnit from '@/components/DesignForm/pageList/types'
|
|
|
|
|
|
import Sortable from 'sortablejs'
|
|
//引入子组件
|
|
import PageListHeadTools from '@/views/sysworkflow/lowcodepage/pageListHeadTools.vue'
|
|
import ControlSetup from '@/views/sysworkflow/lowcodepage/pageSetUpDialog/controlSetup.vue'
|
|
import FieldSetUp from '@/views/sysworkflow/lowcodepage/pageSetUpDialog/fieldSetUp.vue'
|
|
|
|
|
|
const props = defineProps({
|
|
formKey:{
|
|
type:String,
|
|
default:""
|
|
},
|
|
formVersion:{
|
|
type:String,
|
|
default:""
|
|
},
|
|
tabsActive:{
|
|
type:Number,
|
|
default:1
|
|
},
|
|
state:{
|
|
type:Object,
|
|
default(){
|
|
return {}
|
|
}
|
|
}
|
|
});
|
|
|
|
const emits = defineEmits<{
|
|
(e: 'update:state', val: formStruct): void
|
|
(e: 'update:formKey', val: string): void
|
|
(e: 'update:formVersion', val: string): void
|
|
(e: 'judgeFlowIsEdit', val: boolean): void
|
|
(e: 'runNextWindows', val: number): void
|
|
(e: 'closeFormPage'): void
|
|
}>()
|
|
|
|
const statePro = computed({
|
|
get() {
|
|
return props.state
|
|
},
|
|
set(val: formStruct) {
|
|
emits('update:state', val)
|
|
}
|
|
});
|
|
|
|
const formTableActive = ref(1)
|
|
const pageLoading = ref(false)
|
|
//自定义列表结构
|
|
const state = reactive({
|
|
tableData: {
|
|
// tableProps: {}, //表格所有参数
|
|
columns: [],
|
|
config: {},
|
|
controlBtn:[],
|
|
operateBtn:[]
|
|
},
|
|
searchData: {},
|
|
loading: false,
|
|
attrObj: {},
|
|
config: {},
|
|
tagList: {},
|
|
formId: props.formKey || '',
|
|
formList: [], // 所有可选表单数据源
|
|
name: '',
|
|
treeData: {}, // 左侧树相关
|
|
previewVisible: false,
|
|
tabsName: 'second',
|
|
formFieldList: [], // 表单数据源所有可选字段
|
|
dict: {},
|
|
refreshTable: true
|
|
})
|
|
|
|
const kaif = (id: number, callback?: (list: any) => void) => {
|
|
// const content = stringToObj(props.state.formData)
|
|
console.log('获取当前数据下所有字段',statePro.value.formData)
|
|
filterFiled(statePro.value.formData)
|
|
callback && callback(statePro.value.formData.list)
|
|
|
|
console.log('获取当前数据下所有字段--->',state.formFieldList)
|
|
}
|
|
const filterFiled = (obj: any) => {
|
|
obj?.list.forEach((item: FormList) => {
|
|
if (item.type === 'grid' || item.type === 'tabs') {
|
|
item.columns.forEach((col: FormList) => {
|
|
filterFiled(col)
|
|
})
|
|
} else if (['card', 'div'].includes(item.type)) {
|
|
filterFiled(item)
|
|
} else if (!excludeType.includes(item.type) && item.name) {
|
|
state.formFieldList.push({
|
|
prop: item.name,
|
|
label: item.formItem?.label,
|
|
help: item.config.help || ''
|
|
})
|
|
}
|
|
})
|
|
}
|
|
const excludeType = [
|
|
'txt',
|
|
'title',
|
|
'table',
|
|
'component',
|
|
'upload',
|
|
'button',
|
|
'tinymce',
|
|
'inputSlot',
|
|
'flex'
|
|
]
|
|
|
|
const powerUnitAry = ref<any>({
|
|
nodeKey:"",
|
|
recUnitAry:{
|
|
masterUnitList:[],
|
|
sunUnitList:[],
|
|
unitAllKey:[],
|
|
unitAllState:[]
|
|
}
|
|
})
|
|
const formTableField = reactive<formTableField>({})
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-13 08:24:54
|
|
@ 功能: 解析表单
|
|
*/
|
|
const jieForm = () => {
|
|
// analysisForm({nodeKey:"begin",nodeJson:JSON.stringify(statePro.value.formData)})
|
|
// .then((data)=>{
|
|
// if(data.code == 0){
|
|
// powerUnitAry.value = data.data
|
|
// }
|
|
// })
|
|
if(props.formKey != ""){
|
|
gainFormTableField({id:props.formKey.toString()})
|
|
.then((data)=>{
|
|
console.log('解析表单--->',data)
|
|
formTableField.masterTable=data.data.masterTable
|
|
formTableField.sunTable=data.data.sunTable
|
|
})
|
|
}
|
|
|
|
}
|
|
const handleSelectionChange = (val: User[]) => {
|
|
console.log('表单选中--->',val)
|
|
}
|
|
// watch(()=>statePro.value,()=>{
|
|
// jieForm()
|
|
// },
|
|
// {
|
|
// deep: true
|
|
// })
|
|
watch(()=>props.tabsActive,(val:number)=>{
|
|
if(val == 3){
|
|
jieForm()
|
|
}
|
|
})
|
|
onMounted(()=>{
|
|
jieForm()
|
|
nextTick(() => {
|
|
columnDrop()
|
|
})
|
|
})
|
|
const setUpFieldInfo = ref<tableButton>()
|
|
const setUpFieldIsOpen= ref(false)
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-25 11:51:46
|
|
@ 功能: 设置字段属性
|
|
*/
|
|
const setUpField = (val:any) =>{
|
|
console.log("设置字段属性-->",val)
|
|
setUpFieldInfo.value = val
|
|
|
|
setUpFieldIsOpen.value = true
|
|
|
|
console.log("设置字段属性-1->",setUpFieldIsOpen)
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-27 09:17:15
|
|
@ 功能: 设置功能按钮
|
|
*/
|
|
const listButtonIsShow = ref(false)
|
|
const setUpFieldBut = () => {
|
|
// console.log("设置字段属性-->")
|
|
listButtonIsShow.value = true
|
|
}
|
|
//功能按钮
|
|
const tableAttrButClick = (val:tableButton[]) => {
|
|
if(state.tableData.controlBtn.length > 0){
|
|
state.tableData.controlBtn.splice(0, state.tableData.controlBtn.length);
|
|
state.tableData.controlBtn = val
|
|
}else{
|
|
state.tableData.controlBtn = val
|
|
}
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-25 14:58:22
|
|
@ 功能: 功能字段
|
|
*/
|
|
const tableFieldAttrButClick = (val:tableButton[]) => {
|
|
if(val.length > 0){ //判断是否有选中的字段
|
|
if(state.tableData.columns.length > 0){ //判断列表是否有数据
|
|
val.forEach((item:tableButton)=>{
|
|
let isTrue = true;
|
|
state.tableData.columns.forEach((itemTab:tableButton)=>{
|
|
if(item.id == itemTab.id){
|
|
isTrue = false;
|
|
}
|
|
});
|
|
if(isTrue){
|
|
state.tableData.columns.push(item)
|
|
}
|
|
})
|
|
}else{ //列表无数据,直接新增
|
|
val.forEach((item:tableButton)=>{
|
|
state.tableData.columns.push(item)
|
|
})
|
|
}
|
|
//此处往下是处理列表中有为选中的字段
|
|
let delField = []
|
|
tableAttrLogButtonList.forEach((item:tableButton)=>{
|
|
let isTrue = true;
|
|
val.forEach((itemVal:tableButton)=>{
|
|
if(item.id == itemVal.id){
|
|
isTrue = false
|
|
}
|
|
})
|
|
if(isTrue){
|
|
delField.push(item.id)
|
|
}
|
|
});
|
|
if(delField.length > 0){
|
|
state.tableData.columns.forEach((itemTab:tableButton,index:number)=>{
|
|
delField.forEach((item:string)=>{
|
|
if(item == itemTab.id){
|
|
state.tableData.columns.splice(index,1) //删除列表中已经存在的字段
|
|
}
|
|
})
|
|
|
|
});
|
|
}
|
|
}else{ //无选中的字段
|
|
if(state.tableData.columns.length > 0){
|
|
tableAttrLogButtonList.forEach((item:tableButton)=>{
|
|
state.tableData.columns.forEach((itemTab:tableButton,index:number)=>{
|
|
if(item.id == itemTab.id){
|
|
state.tableData.columns.splice(index,1) //删除列表中已经存在的字段
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
if(state.tableData.columns.length > 0){
|
|
let isOpent = true;
|
|
state.tableData.columns.forEach((itemTab:tableButton)=>{
|
|
if(itemTab.fieldClass == "__control"){
|
|
isOpent = false;
|
|
}
|
|
});
|
|
if(isOpent){
|
|
state.tableData.operateBtn = [];
|
|
}
|
|
}else{
|
|
state.tableData.operateBtn = [];
|
|
}
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-25 16:36:38
|
|
@ 功能: 列表字段处理
|
|
*/
|
|
const tableListFieldClick = (val:any[]) => {
|
|
console.log("列表字段处理-->",val)
|
|
if(val.length > 0){
|
|
if(state.tableData.columns.length > 0){ //判断列表是否有数据
|
|
val.forEach((item:tableButton)=>{
|
|
let isTrue = true;
|
|
state.tableData.columns.forEach((itemTab:tableButton)=>{
|
|
if(item.id == itemTab.id){
|
|
isTrue = false;
|
|
}
|
|
});
|
|
if(isTrue){
|
|
state.tableData.columns.push(item)
|
|
}
|
|
})
|
|
}else{ //列表无数据,直接新增
|
|
val.forEach((item:any)=>{
|
|
state.tableData.columns.push(item)
|
|
})
|
|
}
|
|
//此处往下是处理列表中有为选中的字段
|
|
let delField = []
|
|
formTableField.masterTable.forEach((item:tableButton)=>{
|
|
let isTrue = true;
|
|
val.forEach((itemVal:tableButton)=>{
|
|
if(item.id == itemVal.id){
|
|
isTrue = false
|
|
}
|
|
})
|
|
if(isTrue){
|
|
delField.push(item.id)
|
|
}
|
|
});
|
|
if(delField.length > 0){
|
|
state.tableData.columns.forEach((itemTab:tableButton,index:number)=>{
|
|
delField.forEach((item:string)=>{
|
|
if(item == itemTab.id){
|
|
state.tableData.columns.splice(index,1) //删除列表中已经存在的字段
|
|
}
|
|
})
|
|
|
|
});
|
|
}
|
|
}else{
|
|
if(state.tableData.columns.length > 0){
|
|
formTableField.masterTable.forEach((item:tableButton)=>{
|
|
state.tableData.columns.forEach((itemTab:tableButton,index:number)=>{
|
|
if(item.id == itemTab.id){
|
|
state.tableData.columns.splice(index,1) //删除列表中已经存在的字段
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
const container = ref()
|
|
//拖动字段排序
|
|
const columnDrop = () => {
|
|
const wrapperTr = container.value.querySelector(
|
|
'.el-table__header-wrapper tr'
|
|
)
|
|
console.log("wrapperTr",wrapperTr)
|
|
Sortable.create(wrapperTr, {
|
|
animation: 180,
|
|
delay: 0,
|
|
onEnd: (evt: any) => {
|
|
// console.log("evt",evt.oldIndex,evt.newIndex)
|
|
const oldItem = state.tableData.columns[evt.oldIndex]
|
|
state.tableData.columns.splice(evt.oldIndex, 1)
|
|
state.tableData.columns.splice(evt.newIndex, 0, oldItem)
|
|
// 重染表格,否则点下面的设置对不上了
|
|
state.refreshTable = false
|
|
nextTick(() => {
|
|
state.refreshTable = true
|
|
nextTick(() => {
|
|
columnDrop() // 拖完后拖不到了,再执行一下
|
|
})
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
const tableFieldList = ref<InstanceType<typeof ElTable>>()
|
|
const tableFieldAttrBut = ref<InstanceType<typeof ElTable>>()
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-27 08:27:22
|
|
@ 功能: 删除表头列表字段
|
|
*/
|
|
const delCol = (val:any) => {
|
|
let delInfo = []
|
|
let delInfoBut = []
|
|
if(state.tableData.columns.length > 0) {
|
|
|
|
state.tableData.columns.forEach((item: any, index: number) => {
|
|
if (item.id === val.id) {
|
|
state.tableData.columns.splice(index, 1)
|
|
if(item.types == "-"){
|
|
delInfoBut.push(item)
|
|
}else{
|
|
delInfo.push(item)
|
|
}
|
|
}
|
|
|
|
})
|
|
|
|
// tableFieldList.value!.toggleRowSelection(delInfo, true)
|
|
console.log("delInfo",delInfo)
|
|
// tableFieldList.value!.clearSelection()
|
|
}else{
|
|
tableFieldList.value!.clearSelection()
|
|
tableFieldAttrBut.value!.clearSelection()
|
|
}
|
|
if(delInfo.length > 0){
|
|
delInfo.forEach((item:any)=>{
|
|
tableFieldList.value!.toggleRowSelection(item, false)
|
|
})
|
|
}
|
|
if(delInfoBut.length > 0){
|
|
delInfoBut.forEach((item:any)=>{
|
|
tableFieldAttrBut.value!.toggleRowSelection(item, false)
|
|
})
|
|
}
|
|
}
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-27 10:13:34
|
|
@ 功能: 更新列表记录操作按钮
|
|
*/
|
|
const updataLogBut = (val:attrButton[]) => {
|
|
console.log("更新列表记录操作按钮",val)
|
|
let isWrete = true
|
|
if(state.tableData.columns && state.tableData.columns.length > 0){
|
|
state.tableData.columns.forEach((item:any)=>{
|
|
if(item.fieldClass == "__control"){
|
|
state.tableData.operateBtn = val.value
|
|
isWrete = false
|
|
}
|
|
})
|
|
}
|
|
if(isWrete){
|
|
state.tableData.operateBtn = [];
|
|
}
|
|
// console.log("更新列表记录操作按钮------1------->",state.tableData.operateBtn)
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
<template>
|
|
<div ref="container" class="design-containers design-table" v-loading="pageLoading">
|
|
<!-- <div class="components-list">
|
|
<el-divider content-position="left">表格列字段</el-divider>
|
|
<el-table
|
|
ref="multipleTableRef"
|
|
:data="powerUnitAry.recUnitAry.masterUnitList"
|
|
style="width: 100%"
|
|
@selection-change="handleSelectionChange"
|
|
>
|
|
<el-table-column type="selection" width="30" />
|
|
<el-table-column label="栏目">
|
|
<template #default="scope">{{ scope.row.name }}</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div> -->
|
|
<div class="main-body">
|
|
<div class="header">
|
|
<div class="field">
|
|
</div>
|
|
<PageListHeadTools />
|
|
</div>
|
|
<div class="table_box main_table">
|
|
|
|
<div
|
|
class="search-box"
|
|
>
|
|
<div class="tipBox" >条件查询搜索区域,单击可编辑</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="operateButArea">
|
|
<div>
|
|
<el-text v-if="state.tableData.controlBtn.length === 0" class="mx-1 tipBox" type="info">操作按钮区域</el-text>
|
|
<el-button
|
|
v-for="item in state.tableData.controlBtn"
|
|
v-bind="item"
|
|
:key="item.type"
|
|
>
|
|
{{ item.label }}
|
|
</el-button>
|
|
</div>
|
|
<div>2</div>
|
|
</div>
|
|
|
|
<div class="operateButArea tipBox" v-if="!state.tableData.columns?.length">
|
|
表格列设置区域,可从左上角 添加表格列字段
|
|
选择已有列或直接从上方工具栏 生成脚本预览 编辑
|
|
</div>
|
|
<el-table
|
|
:data="[{}]"
|
|
v-bind="state.tableData.tableProps || {}"
|
|
ref="tableEl"
|
|
v-if="state.refreshTable && state.tableData.columns?.length"
|
|
>
|
|
<template
|
|
v-for="item in state.tableData.columns"
|
|
:key="item.prop || item.label"
|
|
>
|
|
|
|
<el-table-column v-if="item.id == 'checkbox'" fixed type="selection" width="40" align="center" />
|
|
<el-table-column v-else-if="item.field == 'index'" type="index" width="80" align="center">
|
|
<template #header="scope">
|
|
<div class="field_close">
|
|
{{item.name}}
|
|
<i class="field_close fa fa-close" @click="delCol(item)"></i>
|
|
</div>
|
|
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column v-else v-bind="item">
|
|
<template #header="scope">
|
|
|
|
<div class="field_close">
|
|
{{item.name}}
|
|
<i class="field_close fa fa-close" @click="delCol(item)"></i>
|
|
</div>
|
|
<el-tooltip placement="top" v-if="item.help">
|
|
<template #content>
|
|
<span v-html="item.help"></span>
|
|
</template>
|
|
<i class="icon-help"></i>
|
|
</el-tooltip>
|
|
</template>
|
|
<template #default>
|
|
<span v-if="item.fieldClass=='__control'">操作</span>
|
|
<span v-else>数据</span>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
|
|
|
|
</template>
|
|
</el-table>
|
|
<div class="table-tip">
|
|
操作提示:<br />
|
|
*从数据列表配置中选择 所属表单<br />
|
|
*从左上角 添加表格字段 选择预设字段<br />
|
|
*可拖动表头字段移动调整表头字段排列顺序<br />
|
|
*可通过顶部工具栏 生成脚本预览 查看或编辑添加自定义字段
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sidebar-tools">
|
|
<el-tabs ref="multipleTableRef" v-model="formTableActive" class="form_tabs" @tab-click="handleClick">
|
|
<el-tab-pane label="字段设置" :name="1">
|
|
<el-divider content-position="left">功能字段</el-divider>
|
|
<el-table ref="tableFieldAttrBut" :data="tableAttrLogButtonList" border style="width: 100%" @selection-change="tableFieldAttrButClick">
|
|
<el-table-column fixed type="selection" width="40" align="center" />
|
|
<el-table-column prop="name" label="字段" />
|
|
<el-table-column fixed="right" label="设置" width="55" align="center">
|
|
<template #default="scope">
|
|
<el-icon v-if="scope.row.fieldClass=='__control'" title="设置" @click="setUpFieldBut(scope.row)"><Setting /></el-icon>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<el-divider content-position="left">列表字段</el-divider>
|
|
<el-table ref="tableFieldList" :data="formTableField.masterTable" border @selection-change="tableListFieldClick" style="width: 100%">
|
|
<el-table-column fixed type="selection" width="40" align="center" />
|
|
<el-table-column prop="name" label="字段">
|
|
<template #default="scope">
|
|
{{scope.row.name}}({{scope.row.fieldClass}}[{{scope.row.pattern}}])
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column fixed="right" label="设置" width="55" align="center">
|
|
<template #default="scope">
|
|
<el-icon title="设置" @click="setUpField(scope.row)"><Setting /></el-icon>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<el-divider content-position="left">查询条件</el-divider>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="列表设置" :name="2">
|
|
<el-divider content-position="left">批量操作</el-divider>
|
|
<el-divider content-position="left">功能按钮</el-divider>
|
|
<el-table ref="tableAttrBut" :data="tableButtonList" border style="width: 100%" @selection-change="tableAttrButClick">
|
|
<el-table-column fixed type="selection" width="40" align="center" />
|
|
<el-table-column prop="label" label="字段" />
|
|
</el-table>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
<!-- {{props.formKey}}
|
|
<br>
|
|
{{props.formVersion}}
|
|
<br>
|
|
{{formTableField}} -->
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<FieldSetUp v-model:is-open="setUpFieldIsOpen" :setup-field-info="setUpFieldInfo" />
|
|
|
|
|
|
<ControlSetup v-model:is-show="listButtonIsShow" v-model:contbutary:="state.tableData.operateBtn" @updata-log-but="updataLogBut" />
|
|
</div>
|
|
</template>
|
|
<style lang='scss' scoped>
|
|
.design-containers{
|
|
display: flex;
|
|
background-color: #FFFFFF;
|
|
margin: 0;
|
|
.components-list{
|
|
width: 200px;
|
|
padding: 0;
|
|
overflow-y: auto;
|
|
height: calc(100vh - 40px);
|
|
position: relative;
|
|
overflow-x: hidden;
|
|
border-right: 1px solid #e0e0e0;
|
|
}
|
|
}
|
|
.form_tabs > .el-tabs__content{
|
|
padding: 0;
|
|
}
|
|
.table_box{
|
|
background: #fff;
|
|
border: 1px dashed #999;
|
|
margin: 10px;
|
|
height: calc(100vh - 100px);
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
position: relative;
|
|
.table-tip{
|
|
color: #999;
|
|
padding: 30px 0;
|
|
line-height: 22px;
|
|
}
|
|
.operateButArea{
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
.main_table{
|
|
padding: 10px 20px;
|
|
}
|
|
.field_close{
|
|
i{
|
|
|
|
display: none;
|
|
}
|
|
|
|
|
|
}
|
|
.field_close:hover{
|
|
i{
|
|
display: inline;
|
|
cursor: pointer;
|
|
}
|
|
|
|
}
|
|
.tipBox{
|
|
border: 1px dotted #ddd;
|
|
padding: 3px 5px;
|
|
border-radius: 5px;
|
|
color: #999;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
margin-top: 15px;
|
|
}
|
|
</style>
|
|
|