<!--
@ 作者: 秦东
@ 时间: 2025-06-11 08:11:22
@ 备注: 表单组件循环(新版)
-->
<script lang='ts' setup>
import { Md5 } from 'ts-md5'
import { debounce } from '@/utils/lowCode/item/index'
import { uploadUrl } from '@/api/lowCode/form/fieldUnit'
import { 
    constFormProps,
    constControlChange,
    constGetControlByName,
    constSetFormOptions
} from '@/api/lowCode/utils';
import validate from "@/api/lowCode/form/validate"
import { AnalysisCss,AnalysisInputCss } from '@/api/common/cssInfo'         //样式解析
//辅助控件
import InputPage from '@/components/lowCode/assistant/inputPage.vue'
import DigitpagePage from '@/components/lowCode/assistant/digitpage.vue'  
import TextareaPage from  '@/components/lowCode/assistant/textareaPage.vue'  
import RadioPage from  '@/components/lowCode/assistant/radioPage.vue'  
import CheckboxPage from '@/components/lowCode/assistant/checkboxPage.vue'  
import SelectPage from '@/components/lowCode/assistant/selectPage.vue'  
import CascaderPage from '@/components/lowCode/assistant/cascader.vue'  
import DatePickerPage from '@/components/lowCode/assistant/datePicker.vue'
import TimePickerPage from '@/components/lowCode/assistant/timePickerPage.vue'
import OrgCitys from '@/components/lowCode/assistant/orgCitys.vue'
import SwitchPage from '@/components/lowCode/assistant/switchPage.vue'
import InputNumberPage from '@/components/lowCode/assistant/inputNumberPage.vue'
import LowcodeImagePage from '@/components/lowCode/assistant/lowcodeImage.vue'
import VideoUpAndPlay from '@/components/lowCode/assistant/videoUpAndPlay.vue' 
import UploadPage from '@/components/lowCode/assistant/uploadPage.vue'
import UrlLinkPage from '@/components/lowCode/assistant/urlLink.vue' 
import BaiDuMapPage from '@/components/lowCode/assistant/baiDuMap.vue' 
import QuillEditor from '@/components/lowCode/assistant/quillEditor.vue'
import LowcodeCarsusel from '@/components/lowCode/assistant/lowcodeCarsusel.vue'  
import SignatureMap from '@/components/lowCode/assistant/signatureMap.vue'  
import LowcodeTransfer from '@/components/lowCode/assistant/lowcodeTransfer.vue'  
import ColorPickerPage from '@/components/lowCode/assistant/colorPickerPage.vue'  
import TreeSelectPage from '@/components/lowCode/assistant/treeSelectPage.vue' 
import AssociatedForms from '@/components/lowCode/assistant/associatedForms.vue' 
import SerialNumber from '@/components/lowCode/assistant/serialNumber.vue' 
import ExpandUser from '@/components/lowCode/assistant/rangedUser.vue'
import OrgCentent from '@/components/lowCode/assistant/org.vue' 
import FounderForm from '@/components/lowCode/assistant/founder.vue'
import FounderTime from '@/components/lowCode/assistant/founderTime.vue'
import EditTime from '@/components/lowCode/assistant/editTime.vue'
import OwnerPage from '@/components/lowCode/assistant/ownerPage.vue' 
import DepartmentOrg from '@/components/lowCode/assistant/departmentOrg.vue' 
import PickRole from '@/components/lowCode/assistant/pickrole.vue'
import PickPost from '@/components/lowCode/assistant/pickpost.vue'  

const props = withDefaults(
    defineProps<{
		data: FormList
		modelValue?: any // 子表和弹性布局时时有传
		tProp?: string // 子表时的form-item的prop值，用于子表校验用
		nodeKey?:string
		purview?:any[]
		optionsValue3Get1?:any
		tablekey?:any      
		numrun?:any
		rowIndex?:any
    }>(),
    {}
)
const emits = defineEmits<{
    (e: 'update:modelValue', val: any): void
	(e: 'optionsValue3Get1', val: any,fieldName: string): void
	(e: 'asfValueChanged', val: any): void
}>()
const formProps = inject(constFormProps, {}) as any
const imgUploadApiUrl = import.meta.env.VITE_APP_BASE_API+"/api/upordown" //默认图片
//执行类型
const type = computed(() => {
    return formProps.value.type
})
//配置
const config = computed(() => {
    return props.data.config || {}
})
//组件css部分
const configStyle = computed(() => {
    return props.data.styles || {}
})
const control = computed(() => {
	if(props.data.type == "upload"){
		props.data.control.action = uploadUrl
	}
    return props.data.control
})
const options = ref(props.data.options) //附属属性值
const changeEvent = inject(constControlChange, '') as any
//获取值
const value = computed({
    get() {
		if (props.tProp) {
			// 表格和弹性布局
			return props.modelValue
		} else {
			if(props.data.type == "checkbox"){
				if (formProps.value.model[props.data.name] == null || formProps.value.model[props.data.name] == ""){
					// formProps.value.model[props.data.name] = []
					// return formProps.value.model[props.data.name]
					return []
				}else{
					return formProps.value.model[props.data.name]
				}
			}else{
				return formProps.value.model[props.data.name]
			}
			
		}
    },
    set(newVal: any) {
		if (props.tProp) {
			emits('update:modelValue', newVal)
		}
		updateModel(newVal)
    }
})
const getControlByName = inject(constGetControlByName) as any
// 对单选多选select设置options
const formOptions = inject(constSetFormOptions, {}) as any
//更新数值
const updateModel = (val: any) => {
	let controlAttribute = ""
	if(props.data.control){
		if(props.data.control.type){
			controlAttribute = props.data.control.type
		}
	}
    changeEvent &&
    changeEvent({
        key: props.data.name,
        value: val,
        data: props.data,
        tProp: props.tProp,
		type: props.data.type,
		attribute: controlAttribute
    })
}
// 返回当前item项的校验规则
const itemRules = computed(() => {
    let temp
    const itemR: any = props.data.item?.rules || []
    const customR = formatCustomRules()
    // 如果三个都没有设置，则返回undefined
    if (itemR?.length || customR?.length) {
      	temp = [...customR, ...itemR]
    }
    return temp
})
// 处理自定义校验规则，将customRules转换后追加到rules里
const formatCustomRules = () => {
    const rulesReg: any = {}
    validate &&
    validate.forEach(item => {
        rulesReg[item.type] = item.regExp
    })

    // 获取校验方法 父级使用provide方法注入
    const temp: any = []
    props.data.customRules?.forEach((item: any) => {
		if (!item.message && item.type !== 'methods') {
			return // 方法时允许提示信息为空
		}
		let obj = {}
		if (item.type === 'required') {
			obj = { required: true }
		} else if (item.type === 'rules') {
			// 自定义表达式
			obj = { pattern: item.rules }
		} else if (item.type === 'methods') {
			// 方法时
			const methods: any = item.methods
			if (methods) {
			obj = { validator: inject(methods, {}) }
			}
		} else if (item.type) {
			obj = { pattern: rulesReg[item.type as string] }
		}
		// 这里判断下防某些条件下重复push的可能或存重复校验类型
		let message: any = { message: item.message }
		if (!item.message) {
			// 当使用validator校验时，如果存在message字段则不能使用 callback(new Error('x'));的提示
			message = {}
		}
		temp.push(
			Object.assign(
				{
					trigger: item.trigger || 'blur'
				},
				obj,
				message
			)
		)
    })
    return temp
}
/**
@ 作者: 秦东
@ 时间: 2024-07-27 15:11:42
@ 功能: 判断是否禁用
*/
const judgeIsDisabled = (key:string)  => {
    return false
	if (type.value === 3) {
      	return true // 查看模式，为不可编辑状态
    }
    if (type.value === 1 && config.value.addDisabled) {
      	return true
    }
    if (type.value === 2 && config.value.editDisabled) {
      	return true // 编辑模式
    }
	if(props.nodeKey != undefined && props.purview != undefined && props.purview != null && props.purview != null && props.purview != "" && props.purview != "") {
		if(props.purview.length < 1){
			return false;
		}else{
			let isShow = true;
			props.purview.forEach((item)=>{
				if(item.nodeKey == props.nodeKey){
					
					if(item.powerAry && item.powerAry.length > 0){
						item.powerAry.forEach((itm)=>{
							if(itm.id == key){
								console.log("判断此组件是否禁用",itm,itm.id == key,"--------->",itm.isLook)
								isShow =  !itm.isEdit
								
							}
						})
					}
				}
				
			})
			return isShow
		}
	}else{
		return false;
	}
}
/**
@ 作者: 秦东
@ 时间: 2024-11-13 14:36:08
@ 功能: 解析css
*/
const getFormItemLableStyle = (ele: any) => {
    if(ele?.labelStyle){ 
    //   console.log("返回栅格宽度3",AnalysisCss(ele))
    	return AnalysisCss(ele?.labelStyle)
    }
}
const getFormItemInputStyle = (ele: any,sty:number) => {
    if(ele?.inputStyle){
    //   console.log("返回栅格宽度4",AnalysisInputCss(ele?.inputStyle,sty))
      return AnalysisInputCss(ele?.inputStyle,sty)
    }
}
//获取标签
const getLabel = (ele: FormItem) => {
    const showColon = formProps.value.showColon ? '：' : ''
    if (ele) {
    	return ele.showLabel ? '' : ele.label + showColon
    } else {
      	return ''
    }
}
function asfValueChanged(val:any){
	emits("asfValueChanged",val)
}

const  updateContentVideo =  (val: any) => {
    console.log("更新数据-------->",val)
    //alert(1)
    value.value = val;
    /* props.data.control.videoMsg[0].url = val;
    console.log("更新数据-------->", val);
    console.log("更新数据----1---->", value.value);
    console.log("更新数据----2---->", props.data.control.videoMsg[0].url); */
};
/**
@ 作者: 秦东
@ 时间: 2024-11-13 16:18:59
@ 功能: 自定义组件
*/
const currentComponent = computed(() => {
    switch(props.data.type){
        case "component":
            // 自定义组件
            return config.value.componentName;
            break;
        case "input":
        case "password":
            return markRaw(InputPage);
            break;
        case "digitpage":
            return markRaw(DigitpagePage);
            break;  
        case "textarea":
        case "description":
            return markRaw(TextareaPage);
            break;  
        case "radio":
            return markRaw(RadioPage);
            break;   
        case "checkbox":
            return markRaw(CheckboxPage);
            break;     
        case "select":
            return markRaw(SelectPage);
            break;   
        case "cascader":
            return markRaw(CascaderPage);
            break;
        case "datePicker":
            props.data.control.valueFormat = "x";
      	    return markRaw(DatePickerPage)
            break;  
        case "timePicker":
            props.data.control.valueFormat = "x";
      	    return markRaw(TimePickerPage)
            break;    
        case "organization":
      	    return markRaw(OrgCitys)
            break;
        case "switch":
            return markRaw(SwitchPage)
            break; 
        case "inputNumber":
            return markRaw(InputNumberPage)
            break;  
        case "lowcodeImage":
            return markRaw(LowcodeImagePage)
            break;  
        case "videoUpAndPlay":
            return markRaw(VideoUpAndPlay);
            break  
        case "upload":
            return markRaw(UploadPage);
            break   
        case "urllink":
            return markRaw(UrlLinkPage);
            break      
        case "baidumap":
            return markRaw(BaiDuMapPage);
            break;
        case "tinymce":
            return markRaw(QuillEditor);
            break;
        case "lowcodeCarsusel":
            return markRaw(LowcodeCarsusel);
            break; 
        case "signaturemap":
            return markRaw(SignatureMap);    
            break;
        case "lowcodeTransfer":
            return markRaw(LowcodeTransfer);
            break;  
        case "colorPicker":
            return markRaw(ColorPickerPage);
            break; 
        case "treeSelect":
            return markRaw(TreeSelectPage);
            break;  
        case "associatedForms":   
            return markRaw(AssociatedForms);
            break; 
        case "serialNumber":
            return markRaw(SerialNumber);
            break;  
        case "expand-user":
            return markRaw(ExpandUser);
            break;
        case "orgCentent":
            return markRaw(OrgCentent);
            break;  
        case "founder":
            return markRaw(FounderForm);
            break;
        case "founderTime":
            return markRaw(FounderTime);
            break;
        case "editTime":
            return markRaw(EditTime);
            break;
        case "owner":
            return markRaw(OwnerPage);
            break;  
        case "deptOrg":
            return markRaw(DepartmentOrg);
            break; 
        case "pickpost":
            return markRaw(PickPost);
            break; 
        case "pickrole":
            return markRaw(PickRole);
            break;                                        
        default:
            return `el-${props.data.type}`
    }
})

const testPage = (val:any) =>{
    console.log("刷新数据-------->", val);
}


</script>
<template>
    <el-form-item
        v-bind="data.item"
        :prop="tProp || data.name"
        :class="config.className"
        :label="getLabel(data.item as FormItem)"
        :rules="itemRules"
    >
        <template #label v-if="config.help">
            <span :style="getFormItemLableStyle(configStyle)">{{ getLabel(data.item) }}</span>
            <Tooltips :content="config.help" />
        </template>
        <template #label v-else>
            <span :style="getFormItemLableStyle(configStyle)" >{{ getLabel(data.item) }}</span>
        </template>
        <!-- {{ data.type }} -->
        <!--关联表单-->
        <component
            v-if="['associatedForms'].includes(data.type)"
            :is="currentComponent"
            :data="data"
            :formProps = "formProps"
            v-bind="control"
            :control="control"
            :config="config"
            :name="control.file || 'file'"
            :disabled="judgeIsDisabled(data.name)"
            :options="options"
            :row-index = "rowIndex"
            v-model="value"
            @asf-value-changed="asfValueChanged"
        />
        <!--视频-->
        <component
            v-if="['videoUpAndPlay'].includes(data.type)"
            :types="type"
            :is="currentComponent"
            :data="data"
            v-bind="control"
            :control="control"
            :config="config"
            :name="control.file || 'file'"
            :disabled="judgeIsDisabled(data.name)"
            :options="options"
            v-model="value"
            :val-info="value"
            @updateVideoUrl="updateContentVideo"
            @testPage = "testPage"
        />
        <!--单行文本及密码组件-->
        <component
            v-else
            :types="type"
            :is="currentComponent"
            :data="data"
            v-bind="control"
            :control="control"
            :config="config"
            :name="control.file || 'file'"
            :disabled="judgeIsDisabled(data.name)"
            :options="options"
            v-model="value"
        />
    </el-form-item>
</template>
<style  lang='scss' scoped>

</style>
