|
|
|
|
<!--
|
|
|
|
|
@ 作者: 秦东
|
|
|
|
|
@ 时间: 2024-11-17 16:09:47
|
|
|
|
|
@ 备注: 子表表格循环体
|
|
|
|
|
-->
|
|
|
|
|
<script lang='ts' setup>
|
|
|
|
|
import {
|
|
|
|
|
constFormProps
|
|
|
|
|
} from '@/api/lowCode/utils';
|
|
|
|
|
import { jsonParseStringify } from '@/utils/lowCode/item/index'
|
|
|
|
|
import { SCOPE } from 'element-plus'
|
|
|
|
|
import { onMounted,ref,computed,nextTick } from 'vue';
|
|
|
|
|
import SvgIcon from '@/components/svgIcon/index.vue'
|
|
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{
|
|
|
|
|
data: any;
|
|
|
|
|
type: number;
|
|
|
|
|
tableinfo?: any;
|
|
|
|
|
orgAndManTree?: any;
|
|
|
|
|
}>(),
|
|
|
|
|
{
|
|
|
|
|
data: () => {
|
|
|
|
|
return {}
|
|
|
|
|
},
|
|
|
|
|
type:1
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
const addBtnFlag = ref(true)
|
|
|
|
|
const formProps = inject(constFormProps, {}) as any
|
|
|
|
|
const tableDataNew = computed(() => {
|
|
|
|
|
// console.log("如果编辑页禁用时-----1---->",props.data.name)
|
|
|
|
|
// console.log("如果编辑页禁用时-----2---->",formProps.value.model[props.data.name])
|
|
|
|
|
// console.log("如果编辑页禁用时-----3---->",formProps.value.model)
|
|
|
|
|
// console.log("如果编辑页禁用时-----4---->",formProps.value)
|
|
|
|
|
console.log(formProps.value.model)
|
|
|
|
|
console.log(props.data.name)
|
|
|
|
|
return formProps.value.model[props.data.name]
|
|
|
|
|
})
|
|
|
|
|
const type = computed(() => {
|
|
|
|
|
return formProps.value.type
|
|
|
|
|
})
|
|
|
|
|
// 如果编辑页禁用时,则返回true
|
|
|
|
|
const editDisabled = computed(() => {
|
|
|
|
|
return formProps.value.type === 2 && props.data.config?.editDisabled
|
|
|
|
|
})
|
|
|
|
|
const defaultOneFlag = ref(true)
|
|
|
|
|
if(type.value==1 && props.data.control.defaultOne==2){
|
|
|
|
|
defaultOneFlag.value = false
|
|
|
|
|
}
|
|
|
|
|
const orgAndManTreeLoadedFlag = ref(false)
|
|
|
|
|
|
|
|
|
|
const defaultOneAddedFlag = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 判断树形结构是否存在节点
|
|
|
|
|
*/
|
|
|
|
|
function hasNodesInTree(tree) {
|
|
|
|
|
if (!Array.isArray(tree)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkNode(node) {
|
|
|
|
|
if (node == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const node of tree) {
|
|
|
|
|
if (checkNode(node)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (Array.isArray(node?.children) && hasNodesInTree(node.children)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function lookOrgAndManTreeFinish(){
|
|
|
|
|
|
|
|
|
|
let flag = false
|
|
|
|
|
let i = 0
|
|
|
|
|
props.orgAndManTree.forEach((element: any) => {
|
|
|
|
|
if (element.hasOwnProperty('tree') && hasNodesInTree(element.tree)) {
|
|
|
|
|
i++
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (props.orgAndManTree.length!=0 && i == props.orgAndManTree.length) {
|
|
|
|
|
//alert(i)
|
|
|
|
|
flag = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(flag){
|
|
|
|
|
orgAndManTreeLoadedFlag.value = true
|
|
|
|
|
}else{
|
|
|
|
|
setTimeout(()=>{
|
|
|
|
|
lookOrgAndManTreeFinish()
|
|
|
|
|
},200)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
onMounted(()=>{
|
|
|
|
|
lookOrgAndManTreeFinish()
|
|
|
|
|
autoAddColumnOne()
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function autoAddColumnOne(){
|
|
|
|
|
setTimeout(()=>{
|
|
|
|
|
if(defaultOneFlag.value){
|
|
|
|
|
if(orgAndManTreeLoadedFlag.value){
|
|
|
|
|
//alert(1)
|
|
|
|
|
addColumn()
|
|
|
|
|
defaultOneAddedFlag.value = true
|
|
|
|
|
}else{
|
|
|
|
|
console.log("wait autoAddColumnOne")
|
|
|
|
|
if(defaultOneAddedFlag.value){
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
//console.log(props.data.list)
|
|
|
|
|
let userCompCount = 0
|
|
|
|
|
props.data.list.forEach((item: any) => {
|
|
|
|
|
if(item.type=="expand-user"){
|
|
|
|
|
userCompCount++
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if(userCompCount>0){
|
|
|
|
|
autoAddColumnOne()
|
|
|
|
|
}else{
|
|
|
|
|
waitProvideFormPropsModelDo()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},200)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function waitProvideFormPropsModelDo(){
|
|
|
|
|
setTimeout(()=>{
|
|
|
|
|
if(tableDataNew){
|
|
|
|
|
addColumn()
|
|
|
|
|
defaultOneAddedFlag.value = true
|
|
|
|
|
}else{
|
|
|
|
|
waitProvideFormPropsModelDo
|
|
|
|
|
}
|
|
|
|
|
},200)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const addColumn = () => {
|
|
|
|
|
console.log("如果编辑页禁用时--------->",tableDataNew.value)
|
|
|
|
|
const temp: any = {}
|
|
|
|
|
if (props.data.list) {
|
|
|
|
|
console.log(props.data.list)
|
|
|
|
|
props.data.list.forEach((item: any) => {
|
|
|
|
|
if (item.name) {
|
|
|
|
|
temp[item.name] = item.control.modelValue
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
//console.log(temp)
|
|
|
|
|
|
|
|
|
|
tableDataNew.value.push(jsonParseStringify(temp))
|
|
|
|
|
addBtnFlag.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* //改造这个方法,index为传入的数组下标,要在数组中新增一个元素,元素的属性与其他元素一致,元素的下标为index+1,原来的index之后的元素往后排即可
|
|
|
|
|
const addColumnCurrent=(val:any , index:any) =>{
|
|
|
|
|
console.log(val)
|
|
|
|
|
console.log(index)
|
|
|
|
|
console.log("如果编辑页禁用时--------->",tableDataNew.value)
|
|
|
|
|
const temp: any = {}
|
|
|
|
|
if (props.data.list) {
|
|
|
|
|
props.data.list.forEach((item: any) => {
|
|
|
|
|
if (item.name) {
|
|
|
|
|
temp[item.name] = item.control.modelValue
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
tableDataNew.value.push(jsonParseStringify(temp))
|
|
|
|
|
}
|
|
|
|
|
} */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 删除数组中指定下标的元素
|
|
|
|
|
* @param index 要删除的元素下标
|
|
|
|
|
*/
|
|
|
|
|
const deleteColumnCurrent = (index: any) => {
|
|
|
|
|
console.log("删除元素,下标:", index)
|
|
|
|
|
console.log("删除前数组:", tableDataNew.value)
|
|
|
|
|
|
|
|
|
|
// 验证下标有效性
|
|
|
|
|
if (typeof index !== 'number' && typeof index !== 'string') {
|
|
|
|
|
console.error("删除失败:下标类型无效")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const numIndex = Number(index)
|
|
|
|
|
|
|
|
|
|
// 检查下标是否在有效范围内
|
|
|
|
|
if (isNaN(numIndex) || numIndex < 0 || numIndex >= tableDataNew.value.length) {
|
|
|
|
|
console.error(`删除失败:下标 ${index} 超出范围 (0-${tableDataNew.value.length - 1})`)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 使用 splice 删除指定位置的元素
|
|
|
|
|
const deletedItem = tableDataNew.value.splice(numIndex, 1)
|
|
|
|
|
console.log("删除的元素:", deletedItem[0])
|
|
|
|
|
console.log("删除后数组:", tableDataNew.value)
|
|
|
|
|
|
|
|
|
|
// 返回被删除的元素,便于后续操作(如撤销功能)
|
|
|
|
|
return deletedItem[0]
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("删除操作失败:", error)
|
|
|
|
|
throw error
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const addColumnCurrent = (val: any, index: any) => {
|
|
|
|
|
console.log(val)
|
|
|
|
|
console.log(index)
|
|
|
|
|
console.log("如果编辑页禁用时--------->", tableDataNew.value)
|
|
|
|
|
|
|
|
|
|
if (!props.data.list) return
|
|
|
|
|
|
|
|
|
|
const temp: any = {}
|
|
|
|
|
props.data.list.forEach((item: any) => {
|
|
|
|
|
if (item.name) {
|
|
|
|
|
temp[item.name] = item.control.modelValue
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const newItem = jsonParseStringify(temp)
|
|
|
|
|
|
|
|
|
|
// 计算插入位置,确保在有效范围内
|
|
|
|
|
const insertIndex = Math.min(Math.max(index + 1, 0), tableDataNew.value.length)
|
|
|
|
|
tableDataNew.value.splice(insertIndex, 0, newItem)
|
|
|
|
|
}
|
|
|
|
|
const getText = (text: any,val:any,name:any) => {
|
|
|
|
|
// console.log("text===>",text)
|
|
|
|
|
// console.log("name===>",name)
|
|
|
|
|
// console.log("val===>",val)
|
|
|
|
|
if (typeof text === 'string') {
|
|
|
|
|
return text
|
|
|
|
|
} else {
|
|
|
|
|
return text && text.toString()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const delColumn = (index: number) => {
|
|
|
|
|
tableDataNew.value.splice(index, 1)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
@ 作者: 秦东
|
|
|
|
|
@ 时间: 2024-08-02 13:22:14
|
|
|
|
|
@ 功能: 时间戳转换对象
|
|
|
|
|
*/
|
|
|
|
|
const timeToAry = (timestamp:number) => {
|
|
|
|
|
const date = new Date(timestamp);
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
const month = ('0' + (date.getMonth() + 1)).slice(-2);
|
|
|
|
|
const day = ('0' + date.getDate()).slice(-2);
|
|
|
|
|
const hours = ('0' + date.getHours()).slice(-2);
|
|
|
|
|
const minutes = ('0' + date.getMinutes()).slice(-2);
|
|
|
|
|
const seconds = ('0' + date.getSeconds()).slice(-2);
|
|
|
|
|
return {
|
|
|
|
|
year:year,
|
|
|
|
|
month:month,
|
|
|
|
|
day:day,
|
|
|
|
|
hours:hours,
|
|
|
|
|
minutes:minutes,
|
|
|
|
|
seconds
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
@ 作者: 秦东
|
|
|
|
|
@ 时间: 2024-08-02 13:02:49
|
|
|
|
|
@ 功能: 将时间戳转换成字符串
|
|
|
|
|
*/
|
|
|
|
|
const timeToString = (timeVal:any,types:int) => {
|
|
|
|
|
let timeStr = ""
|
|
|
|
|
if(Array.isArray(timeVal)){
|
|
|
|
|
if(timeVal.length >= 2){
|
|
|
|
|
let startTime = timeToAry(timeVal[0])
|
|
|
|
|
let endTime = timeToAry(timeVal[1])
|
|
|
|
|
switch(types){
|
|
|
|
|
case "year": //年
|
|
|
|
|
timeStr = `${startTime.year} 至 ${endTime.year}`;
|
|
|
|
|
break;
|
|
|
|
|
case "month": //月
|
|
|
|
|
timeStr = `${startTime.year}-${startTime.month} 至 ${endTime.year}-${endTime.month}`;
|
|
|
|
|
break;
|
|
|
|
|
case "datetime": //日期+时间
|
|
|
|
|
timeStr = `${startTime.year}-${startTime.month}-${startTime.day} ${startTime.hours}:${startTime.minutes}:${startTime.seconds} 至 ${endTime.year}-${endTime.month}-${endTime.day} ${endTime.hours}:${endTime.minutes}:${endTime.seconds}`;
|
|
|
|
|
break;
|
|
|
|
|
case "week": //周
|
|
|
|
|
let startWeek = getYearWeek(startTime)
|
|
|
|
|
let endWeek = getYearWeek(endTime)
|
|
|
|
|
timeStr = `${startWeek} 至 ${endWeek}`;
|
|
|
|
|
break;
|
|
|
|
|
case "timeCalss": //时间
|
|
|
|
|
timeStr = `${startTime.hours}:${startTime.minutes}:${startTime.seconds} 至 ${endTime.hours}:${endTime.minutes}:${endTime.seconds}`;
|
|
|
|
|
break;
|
|
|
|
|
case "datetimerange":
|
|
|
|
|
timeStr = `${startTime.year}-${startTime.month}-${startTime.day} ${startTime.hours}:${startTime.minutes}:${startTime.seconds} 至 ${endTime.year}-${endTime.month}-${endTime.day} ${endTime.hours}:${endTime.minutes}:${endTime.seconds}`;
|
|
|
|
|
break;
|
|
|
|
|
case "daterange":
|
|
|
|
|
timeStr = `${startTime.year}-${startTime.month}-${startTime.day} 至 ${endTime.year}-${endTime.month}-${endTime.day}`;
|
|
|
|
|
break;
|
|
|
|
|
case "monthrange":
|
|
|
|
|
timeStr = `${startTime.year}-${startTime.month} 至 ${endTime.year}-${endTime.month}`;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
timeStr = `${startTime.year}-${startTime.month}-${startTime.day} 至 ${endTime.year}-${endTime.month}-${endTime.day}`;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else if(timeVal.length == 1){
|
|
|
|
|
let {year,month,day,hours,minutes,seconds} = timeToAry(timeVal[0])
|
|
|
|
|
switch(types){
|
|
|
|
|
case "year": //年
|
|
|
|
|
timeStr = `${year}`;
|
|
|
|
|
break;
|
|
|
|
|
case "month": //月
|
|
|
|
|
timeStr = `${year}-${month}`;
|
|
|
|
|
break;
|
|
|
|
|
case "datetime": //日期+时间
|
|
|
|
|
timeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
|
|
|
break;
|
|
|
|
|
case "week": //周
|
|
|
|
|
timeStr = getYearWeek(timeVal)
|
|
|
|
|
break;
|
|
|
|
|
case "timeCalss": //时间
|
|
|
|
|
timeStr = `${hours}:${minutes}:${seconds}`;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
timeStr = `${year}-${month}-${day}`
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
timeStr = "未知时间"
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
let {year,month,day,hours,minutes,seconds} = timeToAry(timeVal)
|
|
|
|
|
switch(types){
|
|
|
|
|
case "year": //年
|
|
|
|
|
timeStr = `${year}`;
|
|
|
|
|
break;
|
|
|
|
|
case "month": //月
|
|
|
|
|
timeStr = `${year}-${month}`;
|
|
|
|
|
break;
|
|
|
|
|
case "datetime": //日期+时间
|
|
|
|
|
timeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
|
|
|
break;
|
|
|
|
|
case "week": //周
|
|
|
|
|
timeStr = getYearWeek(timeVal)
|
|
|
|
|
break;
|
|
|
|
|
case "timeCalss": //时间
|
|
|
|
|
timeStr = `${hours}:${minutes}:${seconds}`;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
timeStr = `${year}-${month}-${day}`
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return timeStr
|
|
|
|
|
}
|
|
|
|
|
let associatedFormsIndexTablekey = 0
|
|
|
|
|
const emits = defineEmits<{
|
|
|
|
|
(e: 'asfValueChanged', val: any): void
|
|
|
|
|
}>()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function asfValueChanged(val:any){
|
|
|
|
|
console.log("tablePage-asfValueChanged",val)
|
|
|
|
|
emits("asfValueChanged",val)
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
<template>
|
|
|
|
|
<div></div>
|
|
|
|
|
<div>
|
|
|
|
|
<el-form :model="tableDataNew" :disabled="props.type === 3" label-width="auto" class="formTable">
|
|
|
|
|
<el-card v-for="(itval,itIndex) in tableDataNew" :key="itIndex" class="taskCardBox" shadow="always">
|
|
|
|
|
<template v-for="(item, index) in data.list" :key="index">
|
|
|
|
|
|
|
|
|
|
<el-form-item
|
|
|
|
|
v-if="item.type === 'index'"
|
|
|
|
|
:prop="item.name"
|
|
|
|
|
:label="item.item.label"
|
|
|
|
|
:width="item.item.span"
|
|
|
|
|
>
|
|
|
|
|
<span>{{ itIndex + 1 }}</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<NewFormItem
|
|
|
|
|
v-if="item.type !== 'index'"
|
|
|
|
|
v-model="itval[item.name]"
|
|
|
|
|
:tProp="`${data.name}.${itIndex}.${item.name}`"
|
|
|
|
|
:row-index="itIndex"
|
|
|
|
|
:tableinfo="tableinfo"
|
|
|
|
|
:org-and-man-tree="orgAndManTree"
|
|
|
|
|
:data="item"
|
|
|
|
|
@asf-value-changed="asfValueChanged"
|
|
|
|
|
/>
|
|
|
|
|
</template>
|
|
|
|
|
<template v-if="[1, 2, 4,5,7].includes(type as number) && data.config.delBtnText && !editDisabled" #footer>
|
|
|
|
|
<el-button size="small" type="danger" style="color:#FFFFFF" @click="delColumn(itIndex)">{{
|
|
|
|
|
data.config.delBtnText}}
|
|
|
|
|
</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<el-icon v-if="type == 1 && itIndex > 0" style="float:right; margin-left: 14px;margin-bottom: 13px;margin-right: 5px;" @click="deleteColumnCurrent(itIndex)"><Minus /></el-icon>
|
|
|
|
|
<el-icon v-if="type==1" style="float:right;margin-bottom: 13px;margin-right: 5px;" @click="addColumnCurrent(itval,itIndex)"><Plus /></el-icon>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-form>
|
|
|
|
|
<div
|
|
|
|
|
class="table-btn"
|
|
|
|
|
v-if="[1, 2, 4,5,7].includes(type as number) && data.config.addBtnText && !editDisabled"
|
|
|
|
|
>
|
|
|
|
|
<el-button v-if="!defaultOneFlag&&addBtnFlag" size="small" @click="addColumn">{{ data.config.addBtnText }}</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<style lang='scss' scoped>
|
|
|
|
|
.taskCardBox{
|
|
|
|
|
margin: 5px 0 10px 0;
|
|
|
|
|
}
|
|
|
|
|
.formTable{
|
|
|
|
|
:deep .el-card__body{
|
|
|
|
|
padding: 10px 10px;
|
|
|
|
|
}
|
|
|
|
|
:deep .el-card__footer{
|
|
|
|
|
padding:5px;
|
|
|
|
|
text-align: right;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|