<template>
    <hc-new-card>
        <template #header>
            <div class="w-40">
                <el-select v-model="searchForm.sysId" filterable clearable block placeholder="选择所属系统">
                    <el-option v-for="item in clinets" :key="item.id" :label="item.name" :value="item.id" />
                </el-select>
            </div>
            <div class="ml-3 w-60">
                <hc-search-input v-model="searchForm.name" placeholder="请输入菜单名称" @search="searchClick" />
            </div>
        </template>
        <template #extra>
            <el-button hc-btn type="primary" @click="addClick">新增</el-button>
            <el-button hc-btn type="danger" @click="delClick">删除</el-button>
        </template>
        <hc-table
            ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading"
            :is-index="false" is-new is-check :check-style="{ width: 29 }" lazy :load="tableLoad"
            @selection-change="tableCheckChange"
        >
            <template #sysId="{ row }">
                {{ getSystemNmae(row.sysId) }}
            </template>
            <template #category="{ row }">
                {{ row.category === 1 ? '菜单' : '按钮' }}
            </template>
            <template #action="{ row }">
                <el-link type="warning" @click="editRowClick(row)">修改</el-link>
                <el-link type="success" @click="addRowClick(row)">新增子项</el-link>
                <el-link type="primary" @click="copyRowClick(row)">复制</el-link>
                <el-link type="danger" @click="delRowClick(row)">删除</el-link>
            </template>
        </hc-table>

        <!-- 新增/修改 菜单 -->
        <hc-new-dialog v-model="isDialogShow" widths="800px" is-footer-center :title="iconDialogTitle" @close="dialogClose">
            <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
                <el-row :gutter="20">
                    <el-col :span="8">
                        <el-form-item label="菜单名称：" prop="name">
                            <el-input v-model="formModel.name" clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="路由地址：" prop="path">
                            <el-input v-model="formModel.path" clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="菜单编号：" prop="code">
                            <el-input v-model="formModel.code" clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="菜单图标：">
                            <el-input v-model="formModel.source" clearable>
                                <template #append>
                                    <el-button @click="isIconShow = true">选择图标</el-button>
                                </template>
                            </el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="所属系统：" prop="sysId">
                            <el-select v-model="formModel.sysId" placeholder="选择所属系统" filterable clearable block>
                                <el-option v-for="item in clinets" :key="item.id" :label="item.name" :value="item.id" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="上级菜单：">
                            <el-tree-select
                                v-model="formModel.parentId" placeholder="选择上级菜单"
                                :data="levelMenu" :props="levelMenuProps" clearable filterable check-strictly block :render-after-expand="false"
                            />
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="菜单类型：" prop="category">
                            <div class="form-item-div">
                                <el-radio-group v-model="formModel.category">
                                    <el-radio :label="1">菜单</el-radio>
                                    <el-radio :label="2">按钮</el-radio>
                                </el-radio-group>
                            </div>
                        </el-form-item>
                    </el-col>
                    <el-col v-if="formModel.category === 2" :span="8">
                        <el-form-item label="按钮是否显示：" prop="isShowButton">
                            <div class="form-item-div">
                                <el-radio-group v-model="formModel.isShowButton">
                                    <el-radio :label="2">否</el-radio>
                                    <el-radio :label="1">是</el-radio>
                                </el-radio-group>
                            </div>
                        </el-form-item>
                    </el-col>
                    <el-col v-if="formModel.category === 1" :span="8">
                        <el-form-item label="是否外层：" prop="isLayout">
                            <div class="form-item-div">
                                <el-radio-group v-model="formModel.isLayout">
                                    <el-radio :label="1">否</el-radio>
                                    <el-radio :label="2">是</el-radio>
                                </el-radio-group>
                            </div>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="是否新窗口：" prop="isOpen">
                            <div class="form-item-div">
                                <el-radio-group v-model="formModel.isOpen">
                                    <el-radio :label="1">否</el-radio>
                                    <el-radio :label="2">是</el-radio>
                                </el-radio-group>
                            </div>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="菜单排序：" prop="sort">
                            <el-input-number v-model="formModel.sort" :min="1" block controls-position="right" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="16">
                        <el-form-item label="按钮提示语：">
                            <el-input v-model="formModel.textInfo" clearable :disabled="formModel.category === 1" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="菜单备注：">
                            <el-input v-model="formModel.remark" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item>
                            <template #label>
                                <div class="hc-form-item-label">
                                    <div class="title-content">
                                        <span class="title">菜单备注：</span>
                                        <span content="text">(只能上传MP4格式，且不能用QQ录屏，推荐使用win10自带录屏录制，文件大小限制50兆)</span>
                                    </div>
                                    <div class="right-content">
                                        <el-link type="warning" @click="formModel.videoUrl = ''">清除</el-link>
                                    </div>
                                </div>
                            </template>
                            <hc-form-upload :src="formModel.videoUrl" :num="1" @upload="videoUpload" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="文档信息：">
                            <template #label>
                                <div class="hc-form-item-label">
                                    <div class="title-content">文档信息：</div>
                                    <div class="right-content">
                                        <el-link type="warning" @click="formModel.excelUrl = ''">清除</el-link>
                                    </div>
                                </div>
                            </template>
                            <hc-form-upload :src="formModel.excelUrl" :num="1" @upload="excelUpload" />
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <template #footer>
                <el-button hc-btn @click="dialogClose">取消</el-button>
                <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
            </template>
        </hc-new-dialog>

        <!-- 图标选择 -->
        <hc-menu-icon v-model="isIconShow" @finish="menuIconFinish" />

        <!-- 上传文件 -->
        <hc-upload-file ref="uploadRef" :echo-params="uploadParams" :options="uploadOptions" @success="uploadSuccess" />
    </hc-new-card>
</template>

<script setup>
import { nextTick, onActivated, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { arrToId, formValidate, getArrValue, getObjValue } from 'js-fast-way'
import { delMessage, reloadPage } from '~uti/tools'
import { getClinetAll } from '~api/other'
import { getHeader } from 'hc-vue3-ui'
import mainApi from '~api/system/menu'

//初始组合式
const router = useRouter()
const useRoutes = useRoute()

//激活
onActivated(() => {
    //获取参数
    const { sysId, name } = getObjValue(useRoutes.query)
    searchForm.value = { sysId: sysId, name: name }
    //获取数据
    getClinetAllApi()
    getTableData()
    getLevelMenuData()
})

//获取所有系统
const clinets = ref([])
const getClinetAllApi = async () => {
    const { data } = await getClinetAll()
    clinets.value = getArrValue(data)
}

//获取系统名称
const getSystemNmae = (id) => {
    const item = clinets.value.find((item) => item.id === id)
    return item ? item.name : ''
}

//搜索表单
const searchForm = ref({
    sysId: null, name: null,
})

//搜索
const searchClick = () => {
    router.push({
        name: 'menu',
        query: searchForm.value,
    })
    getTableData()
}

//表格数据
const tableRef = ref(null)
const tableColumn = ref([
    { key: 'name', name: '菜单名称' },
    { key: 'sysId', name: '所属系统' },
    { key: 'path', name: '路由地址' },
    { key: 'code', name: '菜单编号' },
    { key: 'category', name: '菜单类型', width: 90, align: 'center' },
    { key: 'sort', name: '排序', width: 80, align: 'center' },
    { key: 'action', name: '操作', width: 200, align: 'center' },
])

//获取表格数据
const tableLoading = ref(false)
const tableData = ref([{}])
const getTableData = async () => {
    tableData.value = []
    tableLoading.value = true
    const { data } = await mainApi.getLazyList({
        ...searchForm.value,
        parentId: 0,
    })
    tableData.value = getArrValue(data)
    tableLoading.value = false
}

//懒加载表格
const tableLoad = async (row, node, resolve) => {
    const { data } = await mainApi.getLazyList({
        ...searchForm.value,
        parentId: row.id,
    })
    resolve(getArrValue(data))
}

//表格被选择
const tableCheckKeys = ref([])
const tableCheckChange = (rows) => {
    tableCheckKeys.value = rows
}

//上级菜单
const levelMenuProps = {
    label: 'title',
}

const levelMenu = ref([])
const getLevelMenuData = async () => {
    const { data } = await mainApi.getMenuTree()
    levelMenu.value = getArrValue(data)
}

//新增/修改 弹窗
const isDialogShow = ref(false)
const iconDialogTitle = ref('')

//菜单表单
const formRef = ref(null)
const formModel = ref({})
const formRules = {
    name: {
        required: true,
        trigger: 'blur',
        message: '请输入菜单名称',
    },
    path: {
        required: true,
        trigger: 'blur',
        message: '请输入路由地址',
    },
    code: {
        required: true,
        trigger: 'blur',
        message: '请输入菜单编号',
    },
    sysId: {
        required: true,
        trigger: 'blur',
        message: '请选择所属系统',
    },
    category: {
        required: true,
        trigger: 'blur',
        message: '请选择菜单类型',
    },
    isShowButton: {
        required: true,
        trigger: 'blur',
        message: '请选择按钮是否显示',
    },
    isLayout: {
        required: true,
        trigger: 'blur',
        message: '请选择是否外层',
    },
    isOpen: {
        required: true,
        trigger: 'blur',
        message: '请选择是否新窗口',
    },
    sort: {
        required: true,
        trigger: 'blur',
        message: '请输入菜单排序',
    },
}

//图标选择
const isIconShow = ref(false)
const menuIconFinish = (icon) => {
    formModel.value.source = icon
    isIconShow.value = false
}

//新增菜单
const addClick = () => {
    iconDialogTitle.value = '新增菜单'
    formModel.value = {
        category: 1, isOpen: 1, isLayout: 1, isShowButton: 1,
        sort: 1, sysId: searchForm.value.sysId ?? null, parentId: null,
    }
    //显示表单弹窗
    nextTick(() => {
        isDialogShow.value = true
    })
}

//修改菜单
const editRowClick = (row) => {
    formModel.value = {}
    iconDialogTitle.value = '修改菜单'
    formModel.value = { ...row }
    //显示表单弹窗
    nextTick(() => {
        isDialogShow.value = true
    })
}

//新增子项
const addRowClick = (row) => {
    iconDialogTitle.value = '新增子菜单'
    formModel.value = {
        name: row.name, path: row.path, code: row.code, source: row.source,
        sysId: row.sysId, parentId: row.id,
        category: 1, isOpen: 1, isLayout: 1, isShowButton: 1, sort: 1,
    }
    //显示表单弹窗
    nextTick(() => {
        isDialogShow.value = true
    })
}

//复制菜单
const copyRowClick = (row) => {
    iconDialogTitle.value = '复制菜单'
    formModel.value = {
        ...row,
        id: null,
        sort: row.sort + 1,
    }
    //显示表单弹窗
    nextTick(() => {
        isDialogShow.value = true
    })
}

//删除菜单
const delRowClick = (row) => {
    delMessage(async () => {
        const { code, msg } = await mainApi.del(row.id)
        if (code === 200) {
            window.$message.success('删除成功')
            reloadPage()
        } else {
            window.$message.error(msg ?? '删除失败')
        }
    })
}

//批量删除菜单
const delClick = () => {
    const rows = tableCheckKeys.value
    if (rows.length <= 0) {
        window.$message.warning('请选择要删除的菜单')
        return false
    }
    //确认删除菜单
    delMessage(async () => {
        const ids = arrToId(rows)
        const { code, msg } = await mainApi.del(ids)
        if (code === 200) {
            window.$message.success('删除成功')
            reloadPage()
        } else {
            window.$message.error(msg ?? '删除失败')
        }
    })
}


//上传文件
const uploadRef = ref(null)
const uploadParams = ref({})
const uploadOptions = ref({
    url: '/api/blade-resource/oss/endpoint/put-file2',
    headers: getHeader(),
    multiple: false,
})

//上传视频
const videoUpload = () => {
    uploadParams.value = { type: '视频文件' }
    uploadOptions.value.accept = 'video/mp4'
    uploadOptions.value.accept_tip = '只能上传MP4格式，且不能用QQ录屏，推荐使用win10自带录屏录制，文件大小限制50兆'
    uploadOptions.value.size = 50
    nextTick(() => {
        uploadRef.value?.selectFile()
    })
}

//上传文档
const excelUpload = () => {
    uploadParams.value = { type: '文档文件' }
    uploadOptions.value.accept = null
    uploadOptions.value.accept_tip = null
    uploadOptions.value.size = null
    nextTick(() => {
        uploadRef.value?.selectFile()
    })
}

// 文件上传成功的回调
const uploadSuccess = ({ echoParams, resData }) => {
    if (echoParams.type === '视频文件') {
        formModel.value.videoUrl = resData
    } else if (echoParams.type === '文档文件') {
        formModel.value.excelUrl = resData
    }
    //关闭弹窗
    uploadRef.value?.setModalShow(false)
}

//提交表单
const submitLoading = ref(false)
const dialogSubmit = async () => {
    const formRes = await formValidate(formRef.value)
    if (!formRes) return false
    submitLoading.value = true
    //处理数据
    const form = formModel.value
    form.parentId = form.parentId ?? 0
    form.alias = form.alias ?? form.code
    //发起请求
    const { error, code, msg } = await mainApi.submit(form)
    submitLoading.value = false
    if (!error && code === 200) {
        dialogClose()
        window?.$message?.success('操作成功')
        reloadPage()
    } else {
        window?.$message?.error(msg ?? '操作失败')
    }
}

//关闭弹窗
const dialogClose = () => {
    isDialogShow.value = false
    submitLoading.value = false
    formModel.value = {}
}
</script>
