<!--
 * @Description : 通用表格模块
 * @Author      : jinxin
 * @Date        : 2023-02-01 11:53:59
-->
<template>
    <div class="btn-group" v-if="data.tableHeader && data.tableHeader.length > 0">
        <span v-for="(item,index) in data.tableHeader" :key="index" @click="comBtnClick(item)">{{ item.name }}</span>
    </div>
    <vxe-table ref="getDom" class="my-table" border resizable height="600" :scroll-x="{enabled: false}"
        :row-config="{isHover: true}" :scroll-y="{enabled: false}" :data="data.list" :edit-rules="validRules"
        @checkbox-change="getSelectRow" @checkbox-all="getSelectRow"
        :show-footer="data.showFooter" :footer-method="footerMethod"
        :merge-footer-items="data.mergeFooterItems"
        :edit-config="{trigger: 'click', mode: 'cell',showStatus: true}"
        :column-config="{resizable:true}">
        <div v-for="(item,index) in data.listHeader" :key="index + data.headerIndex">
            <!-- 复选 -->
            <vxe-column v-if="item.type == 'checkbox'" :type="item.type" :align="item.align"
            :width="item.width"></vxe-column>
            <!-- 索引、序号 -->
            <vxe-column v-if="item.type == 'index'" :field="item.field" :title="item.title"
            :width="item.width" :align="item.align"></vxe-column>
            <!-- 文本 -->
            <vxe-column v-if="item.type == 'text'" :field="item.field" :title="item.title" :width="item.width"
            :align="item.align"></vxe-column>
            <!-- 输入框 -->
            <vxe-column v-if="item.type == 'editable_ipt'" :field="item.field" :title="item.title" show-overflow
            :width="item.width" :align="item.align" :edit-render="{autofocus:'.vxe-input--inner'}">
                <template #edit="scope">
                    <vxe-input v-model.trim="scope.row[item.field]" type="text" :disabled="data.isDisabled"
                    @blur="clearNull(scope.row[item.field],scope.$rowIndex,item.field)" @change="getDom.updateStatus(scope)">
                    </vxe-input>
                </template>
            </vxe-column>
            <!-- 选择框 -->
            <vxe-column v-if="item.type == 'editable_sel'" :field="item.field" :title="item.title" :width="item.width"
            :align="item.align" :edit-render="{}">
                <template #default="{ row }">
                    <span>{{ getFixedName(row[item.field],'select',data[item.beforeStr + 'list']) }}</span>
                </template>
                <template #edit="{ row }">
                    <vxe-select :disabled="data.isDisabled" v-model="row[item.field]" transfer>
                        <vxe-option v-for="it in data[item.beforeStr + 'list']" :key="it.id" :value="it.id" :label="it.name"></vxe-option>
                    </vxe-select>
                </template>
            </vxe-column>
            <!-- 模糊匹配 -->
            <vxe-column v-if="item.type == 'editable_mhsel'" :field="item.field" show-overflow
            :title="item.title" :width="item.width" :align="item.align" :edit-render="{}">
                <template #default="scope">
                    <span>{{ getFixedName(scope.row[item.field],'mh_sel',data[item.beforeStr + 'list'][scope.$rowIndex]) }}</span>
                </template>
                <template #edit="scope">
                    <el-select :disabled="data.isDisabled" v-model="scope.row[item.field]" filterable remote clearable
                    reserve-keyword :remote-method="(query)=>{getComList(query,scope.$rowIndex,item)}"
                    :popper-append-to-body="false" placeholder="可搜索">
                        <el-option v-for="(it,index) in data[item.beforeStr + 'list'][scope.$rowIndex]" :key="index" :label="it.name" :value="it.id">
                        </el-option>
                    </el-select>
                </template>
            </vxe-column>
            <!-- 复选框 -->
            <vxe-column v-if="item.type == 'check_box_if'" :field="item.field" :title="item.title" :width="item.width"
            :align="item.align" :edit-render="{}">
                <template #default="{ row }">
                    <span>{{ getFixedName(row[item.field],'whether') }}</span>
                </template>
                <template #edit="{ row }">
                    <vxe-checkbox :disabled="data.isDisabled" v-model="row[item.field]" content=""></vxe-checkbox>
                </template>
            </vxe-column>
            <!-- 开关 -->
            <vxe-column v-if="item.type == 'switch'" :field="item.field" :title="item.title" :width="item.width"
            :align="item.align" :edit-render="{}">
                <template #default="{ row }">
                    <span>{{ getFixedName(row[item.field],'switch') }}</span>
                </template>
                <template #edit="scope">
                    <vxe-switch v-model="scope.row[item.field]" open-label="开" close-label="关" :open-value='1' :close-value='0' :disabled="data.isDisabled">
                    </vxe-switch>
                </template>
            </vxe-column>
            <!-- 跳转 -->
            <vxe-column v-if="item.type == 'router'" :field="item.field" :title="item.title" :width="item.width"
            :align="item.align">
                <template #default="{ row }">
                    <span class="router-links" @click="linkJump(row)">{{ row.links }}</span>
                </template>
            </vxe-column>
            <!-- 图片 -->
            <vxe-column v-if="item.type == 'img'" :field="item.field" :title="item.title"
              :width="item.width" :align="item.align">
              <template #default="scope">
                <img :src="scope.row.cover ? scope.row.cover : defaulImg" class="avatar"
                  @error="e => {e.target.src = defaulImg}" />
              </template>
            </vxe-column>
            <!-- 上传 -->
            <vxe-column v-if="item.type == 'img_upload'" :field="item.field" :title="item.title" :width="item.width"
            :align="item.align">
            <template #default="{ row }">
                <el-upload :action="data.upLoadUrl" :with-credentials="true" :on-success="function (res, file, file_list) {
                                    return handleSuccess(res, file, file_list, row)
                                }" :show-file-list="false" name="file" :limit="1" :data="data.upLoadQuery"
                accept=".png, .jpg" :on-change="handleChange">
                <img v-if="row.image" :src="data.cdn + row.image" class="avatar" @mousemove="entryCellShowImg($event, row)" @mouseout="leaveCellBlurImg(row)"/>
                <el-icon v-else class="el-icon-plus"></el-icon>
                <view v-show="row.showImg" class="img-show position-f" v-if="data.showImgUrl" :style="data.top">
                    <img :src="data.cdn + data.showImgUrl" />
                </view>
                </el-upload>
            </template>
            </vxe-column>
            <!-- 组 - 预留 -->
            <vxe-colgroup v-if="item.type == 'group'" :align="item.align" :title="item.title">
            </vxe-colgroup>
        </div>
    </vxe-table>
</template>

<script>
import { defineComponent, reactive, getCurrentInstance, ref, onMounted, nextTick,watch } from "vue";
import defaulImg from '@/assets/defaulImg.jpg'
import { VXETable } from 'vxe-table'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import getFixedName from '../../../hooks/valueChangeName'
export default defineComponent({
    name: 'ModularTable',
    props:{
        listHeader:Array,
        defaultRow:Array,
        tableHeader:Array,
        beforeStrList:Array,
        mergeColData:Array,
        notice: Number
    },
    emits:['getClickBtnType'],
    components:{},
    setup (props, context) {
        // 获取、创建实例
        const { proxy } = getCurrentInstance()
        let getDom = ref(null)
        let store = useStore()
        let route = useRouter()
        // 生命周期
        onMounted(() => {
            nextTick(()=>{
                data.listHeader = props.listHeader
                data.list = props.defaultRow
                data.tableHeader = props.tableHeader
                data.beforeStrList = props.beforeStrList
                props.mergeColData.length > 0 ? data.mergeFooterItems = props.mergeColData[0].mergeFooterItems : ''
                props.mergeColData.length > 0 ? data.showFooter = true  : data.showFooter = false
                data.addRow = JSON.parse(JSON.stringify(props.defaultRow[0]))
                data.listHeader.reverse()
                data.listHeader.forEach(el => {
                    if (el.children) {
                        el.children.reverse()
                    }
                });
            })
        })
        // 变量
        let data = reactive({
            tableHeader:[],
            listHeader: [],
            list: [],
            addRow:{},
            mtlist: [{ id: 1, name: '测试1' }, { id: 2, name: '测试2' }, { id: 3, name: '测试3' }],
            dsplist:[[]],
            beforeStrList:[],
            selectList: [],
            mergeFooterItems:[],
            showFooter:false,
            headerIndex:1,
            isDisabled:false,
            showImgUrl:'',
            top:'',
            upLoadUrl:process.env.VUE_APP_API_BASEURL + 'admin/v1/product/upload',
            upLoadQuery: {
                type: 'images',
                language_id: store.state.user.language.id || 1
            },
            cdn: store.state.user.cdn
        })
        // 获取选中的行
        const getSelectRow = (selectList) => {
            data.selectList = selectList.records
        }
        // 校验
        const validRules = ref({})
        // 输入框 清除 空格
        const clearNull = (value, index, key) => {
            if (value) 
                data.list[index][key] = value.replace(/\s/g, "")
                getDom.value.data[index][key] = value.replace(/\s/g, "")
        }
        // 获取远程模糊匹配值
        const getComList = (query,index,item) => {
            if (query) {
                let queryPara = {page: 1,size: 5,value: query}
                proxy.$http.get(item.reqUrl, queryPara).then(res => {
                    if (res.status == 200) {
                        data[item.beforeStr + 'list'][index] = res.data.data
                    }
                })
            }
        }
        // 上传成功
        const handleSuccess = (res, file, files, row) => {
        if (res.status == 200) {
            // row.image = store.state.user.cdn + res.data[0].r_path
            row.image = res.data[0].r_path
        }
        }
        // 图片移入
        const entryCellShowImg = (e, row) => {
            data.showImgUrl = row.image
            row.showImg = true
            data.top = 'top:' + e.clientY + 'px'
        }
        // 图片移出
        const leaveCellBlurImg = (row) => {
            row.showImg = false
            data.showImgUrl = ''
        }
        // 链接跳转
        const linkJump = (row) => {
            alert('跳转')
            // 获取path
            // route.push({ path: '',query: {type: row.id}})
        }
        // 图片上传
        const handleChange = () => {}
        // 顶部铵钮点击事件
        const comBtnClick = async (item) => {
            // 新增行
            if(item.type == 'add'){
                const row = -1
                const $table = getDom.value
                data.beforeStrList.forEach(el => {
                    data[el + 'list'].push([])
                });
                data.addRow.index = data.list.length + 1
                data.list.push(JSON.parse(JSON.stringify(data.addRow)))
                const { row: newRow } = await $table.insertAt(JSON.parse(JSON.stringify(data.addRow)), row)
                await $table.setActiveCell(newRow, data.listHeader[2].field)
                await $table.loadData(data.list)
            // 删除行 
            }else if(item.type == 'del'){
                if (data.selectList.length > 0) {
                    const $table = getDom.value
                    const type = await VXETable.modal.confirm('您确定要删除已选中数据?')
                    if (type == 'confirm') {
                        $table.removeCheckboxRow()
                    }
                    // 源数据删除
                    $table.getRemoveRecords().forEach(el => {
                        data.list = data.list.filter(it => it.index != el.index)
                    });
                    // 删除多源数组
                    $table.getRemoveRecords().reverse().forEach(el => {
                        data.beforeStrList.forEach(ele => {
                            data[ele + 'list'].splice(el.index - 1, 1)
                        });
                    })
                    // 重新计算序号
                    data.list.forEach((el, ind) => {
                        el.index = ind + 1
                    });
                } else {
                    proxy.$message({ type: 'error', message: '请选择需要删除的行!' })
                }
            // 显示列
            }else if(item.type == 'showCol') {
                console.log('control show col')
            }else{
                context.emit('getClickBtnType',item.type,data.selectList)
            }
        }
        // 求合
        const sumNum = (list,field) => {
            let count = 0
            list.forEach(item => {
                count += Number(item[field])
            })
            return count
        }
        // 表尾合计
        const footerMethod = ({columns,data}) => {
            return [
                columns.map((column, columnIndex) => {
                  let arr = []
                  if (columnIndex === 0) {
                    return props.mergeColData[0].name
                  }
                  props.mergeColData[0].field.forEach(el => {
                    arr.push(el)
                  });
                  if (arr.includes(column.property)) {
                    return sumNum(data, column.property)
                  }
                  return null
                })
            ]
        }
        // 监听
        watch(() => props.notice, (v1, v2) => {
            data.headerIndex = data.headerIndex + 1
        })
        return {
            data,
            props,
            proxy,
            getDom,
            context,
            validRules,
            defaulImg,
            getSelectRow,
            getComList,
            clearNull,
            entryCellShowImg,
            leaveCellBlurImg,
            linkJump,
            handleChange,
            handleSuccess,
            comBtnClick,
            getFixedName,
            sumNum,
            footerMethod,
        }
    }

})
</script>

<style>
@import '../../../assets/style/common.scss';
.btn-group{ margin-bottom: 10px;}
</style> 