<!-- 订单列表 -->
<template>
    <view class="zj-uview-form">
        <u-form :model="currentFormData" :ref="refName" :border-bottom="borderBottom" :label-position="labelPosition" :label-width="labelWidth" :label-align="labelAlign" :label-style="labelStyle" >
            <block v-for="(it,index) in currentHeaders" :key='it.key'>
                <view v-if="!it.hide && it.groups === undefined" class="item-bar">
                    <!-- 表单控件分支代码，针对不同表单显示不同的输入控件 -->
                  <!-- <slot></slot>  -->
                    
                    <zj-uview-form-item :item-info.sync="it" :only-read="onlyRead"  @change="onChange" @onEmit="onEmit">
                        <template v-slot:vditor>
                            <slot :name="it.slot"> </slot>
                        </template>
                    </zj-uview-form-item>
                    <!-- <slot :name="it.slot"> </slot> -->
                </view>
                <view v-else class="group-area">
                    <view class="title" v-if="it.title">{{it.title}}</view>
                    <block v-for="(subItem, jj) in it.groups" :key="jj">
                        <view v-if="!subItem.hide" class="item-bar">
                            <zj-uview-form-item :item-info.sync="subItem" :label-width="labelWidth" :only-read="onlyRead" @change="onChange" @onEmit="onEmit" >
                            </zj-uview-form-item>
                            <!-- 表单控件分支代码的镜像，与表单一模一样 -->
                           
                        </view>
                    </block>
                </view>
            </block>
        </u-form>
        
      <u-button v-if="showButton" class="comfirm" type="primary" shape="circle" size="default"  @click="comfirm">确定</u-button> 
      <u-button v-if="showCancle" class="comfirm" type="" shape="circle" size="default"  @click="cancle">取消</u-button> 
    </view>
</template>

<script>
/****************************************
 * @flie zj-form.vue 百度地图坐标点的气泡窗组件 @see zj-baidu-bubble
 * @flie zj-form-item.vue 百度地图坐标点的气泡窗组件 @see zj-baidu-bubble
 * 
 * @brief 表单。该组件生成用户表单。实现新建、修改、编辑、查看。
 * 
 * @param {Array<Object>} headers 数据表头
 * @param {object} formData 生成key-value对象。需sync
 * @param {Boolean} onlyRead 地图坐标数据点，参数说明如下：
 * @note 
 * @description 
 * 
 * @warning 
 * @author Ian.Sieyoo.Zhao
 * @email ian@pku.edu.cn, sieyoo@163.com
 * @version 1.0.0.20210425-alpha
 * @date 2021-04-25
 * ----------------------------------------
 * @history:
 *   <Date>   |   <Version>    |    <Author>     |  <Description>
 * 2021-04-25 | 1.0.0.20210425 | Ian.Sieyoo.Zhao |  修改验证器失效的问题，重整内核
 * ----------------------------------------
 ****************************************/

// import UForm from "./u-form.vue"
// import UFormItem from './u-form-item.vue'
import ZjUviewFormItem from '../zj-uview-form-item/zj-uview-form-item.vue'
import ZjUviewSelect from '../zj-uview-select/zj-uview-select.vue'
import ZjUviewCheckbox from '../zj-uview-checkbox/zj-uview-checkbox.vue'
import ZjUviewCalendar from '../zj-uview-calendar/zj-uview-calendar.vue'
import ZjUviewFiles from '../zj-uview-files/zj-uview-files.vue'
import ZjUviewImages from '../zj-uview-images/zj-uview-images.vue'
import ZjUviewInput from '../zj-uview-input/zj-uview-input.vue'
export default {
    name: 'zj-uview-form',
    // model: {
    //     prop: 'formData',
    //     event: 'formChange'
    // },
    components:{ 
        // UForm,
        // UFormItem,
        ZjUviewFormItem,
        ZjUviewSelect,
        ZjUviewCheckbox,
        ZjUviewCalendar,
        ZjUviewFiles,
        ZjUviewImages,
        ZjUviewInput,
    },
    props: {
        headers: {
            type: Array,
            default () {
                return [
                    {
                        key: 'company_name',
                        label: '公司名称',
                        type: 'text',
                        value: '北京某某科技有限公司',
                        placeholder: "请输入公司名称",
                        rules: [
                            { 
                                required: true, 
                                message: '请输入姓名', 
                                // 可以单个或者同时写两个触发验证方式 
                                trigger: ['change','blur'],
                            }
                        ],
                        required: true,
                    },
                    {
                        key: 'contact_phone',
                        label: '联系方式',
                        value: '13012438790',
                        type: 'number',
                        placeholder: "请输入联系方式",
                        required: true,
                    },
                    // {
                    //     key: 'photos', 
                    //     label: '图片集', 
                    //     value: this.userInfo.avatar,
                    //     max: 3,
                    //     type: 'images',
                    //     action: 'http://57rus.muztak.cn/api/resource_upload_image',
                    //     header: {
                    //         "Content-Type":"multipart/form-data",
                    //         // "Authorization":'Bearer '+ uni.getStorageSync('token') || null
                    //     },
                    //     split: ',',
                    //     editable: true,
                    //     required: true,
                    // },
                    {
                        key: 'file_list',
                        label: '多文件',
                        type: 'files',
                        value:'',
                        config: {
                            name: 'image',
                            showTitle: true,
                            action: 'https://bgapi.hzhuishi.cn/api/uploadImg',
                            headers: {
                                // "Context-Type":"application/json",
                                // "Context-Type":"multipart/form-data", //默认
                                // "Authorization":'Bearer '+ uni.getStorageSync('token') || null
                            },
                            autoUpload: true,
                            fileType: ['jpg', 'png', 'jpge', 'pdf', 'doc'],
                            limit: 3,
                            split: ';',
                            width: 60,
                            height: 60,
                            size: 2,
                            data: { menu: 'sfs'},
                            nodeStatus: 'err',
                            nodeStatusValue: 0,
                            nodeUrl: 'data.url',
                            nodeTitle: 'data.name',
                            nodeSize: 'data.size',
                        },
                        editable: true,
                        required: true,
                    },
                    
                    
                    
                    {
                        groups: [
                            {
                                key: 'business_type',
                                label: '企业类型',
                                type: 'radio',
                                value: 0,
                                placeholder: "选择业务类型",
                                list: [{
                                        value: 0,
                                        label: '民营'
                                    },
                                    {
                                        value: 1,
                                        label: '国企'
                                    },
                                ],
                                customStyle: {marginRight: '15px'},
                                required: true,
                            },
                            {
                                key: 'business_name',
                                label: '业务类型',
                                type: 'checkbox',
                                value: '代账；营业执照办理',
                                placeholder: "选择业务类型",
                                placement: 'row',
                                list: [{
                                        value: '新注册',
                                        label: '新注册'
                                    },
                                    {
                                        value: '商标',
                                        label: '商标'
                                    },
                                ],
                                split: '；',
                                customStyle: {marginRight: '15px'},
                                required: true,
                            },
                            {
                                key: 'contract_term',
                                label: '合同期限',
                                type: 'date',
                                value: '12',
                                placeholder: "请选择合同期限",
                                required: true,
                            },
                            {
                                key: 'cooperate_department',
                                label: '协调部门',
                                type: 'select',
                                // value: '未知',
                                // default:['2','22'],
                                placeholder: "选择协调部门",
                                required: true,
                                list: [
                                    {
                                        value: '1',
                                        label: '中组部',
                                        children: [
                                            {
                                                value: '11',
                                                label: '中央'
                                            },
                                            {
                                                value: '12',
                                                label: '地方'
                                            },
                                        ]
                                    },
                                    {
                                        value: '2',
                                        label: '党政部',
                                        children: [
                                            {
                                                value: '21',
                                                label: '共产党'
                                            },
                                            {
                                                value: '22',
                                                label: '三九学社'
                                            },
                                        ]
                                    },
                                ]
                            },
                        ]
                    },
                    
                    
                    {
                        title: '支付信息',
                        groups: [
                            {
                                key: 'pay_type',
                                label: '付款方式',
                                type: 'select',
                                value: '支付定金',
                                placeholder: "选择付款方式",
                                list: [{
                                        value: '支付全款',
                                        label: '支付全款'
                                    },
                                    {
                                        value: '支付定金',
                                        label: '支付定金'
                                    },
                                    {
                                        value: '不支付',
                                        label: '不支付'
                                    },
                                ],
                                emit: 'onPayModeChange',
                                required: true,
                            },
                            {
                                key: 'order_price',
                                label: '订单金额',
                                type: 'number',
                                placeholder: "请输入金额",
                                unit: '元',
                                tip: '请输入合同金额',
                                required: true,
                            },
                            {
                                key: 'pay_now',
                                label: '支付金额',
                                type: 'number',
                                value:'10000',
                                placeholder: "请输入支付金额",
                                unit: '元',
                                editable: false,
                                required: false,
                            },
                            {
                                key: 'order_remark',
                                label: '订单备注',
                                type: 'textarea',
                                placeholder: "请输入备注",
                                required: true,
                            },
                        ]
                    }
                    
                    
                ]
            }
        },
        // //建议先考虑使用submit事件的表单参数，因为v-mode=""
        // formData: {
        //     type: Object,
        //     default () {
        //         return {}
        //     }
        // },
        showButton: {
            type: Boolean,
            default: true
        },
        showCancle: {
            type: Boolean,
            default: false
        },
        /** 错误的提示方式，见上方说明	*/
        errorType: {
            type: String,
            default: 'message'  // message	none|toast|border-bottom|none
        },
        /** 是否显示表单域的下划线边框	*/
        borderBottom: {
            type: Boolean,
            default: true  // 默认true
        },
        /** 表单域提示文字的位置，left-左侧，top-上方	 */
        labelPosition: {
            type: String,
            default: () => 'left'  // left/top
        },
        /** 提示文字的宽度，单位px */
        labelWidth: {
            type: [String, Number],
            // default: () => ''  // 默认'45px' / auto
        },
        /** lable字体的对齐方式	 */
        labelAlign: {
            type: String,
            default: () => 'left'  // left / center / right
        },
        /** lable的样式，对象形式	 */
        labelStyle: {
            type: Object,
            default: () => ({
                color: '#0070AD',
                fontSize: '13px',
            })
        },
        onlyRead: {
            type: Boolean,
            default: false
        },
    },
    data() {
        return {
            refName: 'zjForm' + (Math.round(Math.random()*100) + 1000),
            currentFormData: {
                // baggage_no: '', //临时加的
                // person_name: '', //临时加的
            },
            
            need_pay : false,
            currentHeaders: [],
        }
    },
    computed:{},
    created(){
    },
    mounted() {
        this.initHeaders();
        this.$nextTick(() => {
           this.initFormRules();
        })
    },
    methods: {
        initHeaders(){
            this.currentHeaders = this.headers;
            this.initDefaultHeaders(this.currentHeaders);
            this.$emit("update:headers", this.currentHeaders);
            this.$emit("update:formData", this.xGetFormData(this.currentHeaders));
            setTimeout(()=>{
                this.$emit("change", this.xGetFormData(this.currentHeaders))
            }, 40);
        },
        //更新表单键值。
        initDefaultHeaders(list){
            for(let i in list){
                if(list[i].groups === undefined){
                    if(list[i].value === undefined)
                        list[i].value = '';
                }
                else{
                    this.initDefaultHeaders(list[i].groups)
                }
                
            }
        },
        //初始化表单规则。根据uView官方文档说明，规则必须在表单的根组件u-form中注入
        initFormRules(){
            let allRules = {}
            for(let it of this.headers){
                if(it.rules){
                    allRules[it.key] = it.rules;
                }
				if (it.groups) {
					for (let v of it.groups) {
						if (v.rules) {
							this.currentFormData[v.key] = v.value;
							allRules[v.key] = v.rules;
						}
					}
                }
            }
            // 通过ref，在onReady生命周期调用组件的setRules方法绑定验证规则，无法通过props传递变量，是因为微信小程序会过滤掉对象中的方法，导致自定义验证规则无效。
            // console.log("allRules:", this.refName, allRules)
            this.$refs[this.refName].setRules(allRules);
            
        },
        async checkVaildate(){
            // console.log('checkVaildate:', this.refName, this.$refs[this.refName]);
            // let isVaild = false
			// this.$refs[this.refName].validate(valid => {
			//     if (valid) {
			//         // console.log('验证通过');
			//         isVaild = true
			//     } 
			//     else {
			//         // console.log('验证失败');
			//     }
			// });
			//    return isVaild;
			
			// 外面调用的时候 async await 就好了
			let isVaild = false
			await this.$refs[this.refName].validate().then(  res => {
				 isVaild = true;
			}).catch( errors => {
				if( errors.length > 0){
					uni.showToast({ title:errors[0].message, icon:'none'})
				}
			})
			return isVaild
			
        },
        xGetFormData: function(list){
            let dataObj = {};
            for(const i in list){
                if(list[i].groups === undefined && list[i].key !== undefined){
                    Object.assign(dataObj, {[list[i].key]: list[i].value});
                }
                else{
                    Object.assign(dataObj, this.xGetFormData(list[i].groups))
                }
            }
            return dataObj;
        },
        
        onChange(e){
            // console.log("onChange:", e)
            this.xSetItemInList(e.key, e, this.currentHeaders)
            
            this.$emit("update:headers", this.currentHeaders);
            this.$emit("update:formData", this.xGetFormData(this.currentHeaders));
            setTimeout(()=>{
                this.$emit("change", this.xGetFormData(this.currentHeaders))
            }, 40);
            // this.checkVaildate();
        },
        onEmit(e){
            this.$emit(e.emitName, e.emitValue)
        },
        comfirm() {
            // console.log("comfirm:" + JSON.stringify(this.formData));
            // 添加表单校验，这里必须要写在$nextTick中，因为u-form的rules是通过ref手动传入的
            // 不在$nextTick中的话，可能会造成执行此处代码时，父组件还没通过ref把规则给u-form，导致规则为空
            // this.$refs.uForm.validate(valid => {
            //     if (valid) {
            //         console.log('验证通过: ' + JSON.stringify(valid));
            //     } else {
            //         console.log('验证失败');gle
            //     }
            // });
			
            this.$emit("update:headers", this.currentHeaders);
            this.$emit("update:formData", this.xGetFormData(this.currentHeaders));
            // console.log("this.xGetFormData(this.currentHeaders)", this.xGetFormData(this.currentHeaders));
            setTimeout(()=>{
                // console.log("comfirm:" + JSON.stringify(this.currentHeaders));
                this.$emit("submit", this.xGetFormData(this.currentHeaders))
            }, 40);
        },
        cancle(){
            this.$emit("cancle:");  
        },
        
        /** 通用方法，在数组中找到key为key的索引
        * @key (String): 需要查找的key，匹配list中对象键名为'key'的位置
        * @list (Array[Object]): 指元素为对象的数组类型，简称对象数组。
        * * @byKey (String): 指定要查找的键值对的键名
        */
        xGetItemInList: function(key, list, byKey='key'){
            let subPos = -1;
            let pos = list.findIndex(it => { 
                if(it.groups === undefined && it[byKey] == key){
                    return true;
                }
                else{
                    subPos = it.groups.findIndex( subItem => subItem[byKey] === key )
                    if(subPos >= 0){
                        return true; 
                    }
                }
            });
            if(pos >= 0){
                return subPos >=0 ? list[pos]['groups'][subPos] : list[pos];
            }
        },
        /** function xSetItemInList() 在多层分组的列表中，查找并替换指定key的值。
        * @key (String): key在多层中必须唯一；
        * @parentItem (Object): 是对象类型；
        * @list (Array[Object]): 指元素为对象的数组类型，简称对象数组。 
        */
        xSetItemInList: function(key, parentItem, list){
            for(let i in list){
                if(list[i].groups === undefined){
                    if(list[i]['key'] === key){
                        list[i] = parentItem;
                    }
                }
                else{
                    this.xSetItemInList(key, parentItem, list[i].groups)
                }
            }
            return list;
        },
        /** 通用方法，在数组中找到key为key的索引，将key为value的值替换
        * @key (String): 需要查找的key，匹配list中对象键名为'key'的位置
        * @value (String): 替换的值，匹配list中对象键名为'value'的值
        * @list (Array[Object]): 指元素为对象的数组类型，简称对象数组。
        * @byValue (String): 指定被替换的键值对的键名
        * @byKey (String): 指定要查找的键值对的键名
        */
        xSetValueInList: function(key, value, list, byValue='value', byKey='key'){
            for(let i in list){
                if(list[i].groups === undefined){
                    if(list[i][byKey] === key){
                        list[i][byValue] = value;
                        return;
                    }
                }
                else{
                    this.xSetValueInList(key, value, list[i].groups, byValue, byKey)
                }
            }
        },
    },
    watch: {
        headers: {
        	handler(val, old) {
        		this.currentHeaders = val;
        		this.initDefaultHeaders(this.currentHeaders);
        		this.$emit("change", this.xGetFormData(this.currentHeaders));
        		this.initFormRules();
        	},
        	deep: true,
        },

    }
}
</script>
<style scoped>
    .zj-uview-form{
        margin: 0;
        /* padding: 0 30rpx 20rpx 30rpx; */
    }
    .comfirm{
        /* margin: 50rpx 50rpx; */
    }
    
    .zj-uview-form .item-bar{}
    /* .zj-uview-form .group-area{margin: 30rpx 0 ; padding: 0 30rpx; border-radius: 30rpx; background: #FFF; box-shadow: 0 0 20rpx rgba(0,0,0,0.1); } */
    .zj-uview-form .group-area{border-bottom: 2px solid #AAA; padding: 10px 0; }
    .zj-uview-form .group-area:last-child{border-bottom: none;}
    .zj-uview-form .group-area .title{ padding: 30rpx 0 20rpx 0; font-size: 36rpx; font-weight: bold; border-bottom: 1px #EEE solid; }
</style>
