<template>
    <div class="p-2">
        <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
            <div class="search" v-show="showSearch">
                <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
                                <el-form-item label="产品名称" prop="productName">
                                    <el-input v-model="queryParams.productName" placeholder="请输入产品名称" clearable style="width: 240px" @keyup.enter="handleQuery" />
                                </el-form-item>
                                <el-form-item label="产品状态" prop="status">
                                    <el-select v-model="queryParams.status" placeholder="请选择产品状态" clearable style="width: 240px">
                                        <el-option
                                            v-for="dict in sys_student_status"
                                            :key="dict.value"
                                            :label="dict.label"
                                            :value="dict.value"
                                        />
                                    </el-select>
                                </el-form-item>
                    <el-form-item>
                        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
                        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
                    </el-form-item>
                </el-form>
            </div>
        </transition>

        <el-card shadow="never">
            <template #header>
                <el-row :gutter="10" class="mb8">
                    <el-col :span="1.5">
                        <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['mf:product:add']">新增</el-button>
                    </el-col>
                    <el-col :span="1.5">
                        <el-button type="success" plain icon="Top" @click="handleImport()" v-hasPermi="['mf:product:import']">导入</el-button>
                    </el-col>
                    <el-col :span="1.5">
                        <el-button type="warning" plain icon="Download" @click="handleExport()" v-hasPermi="['mf:product:export']">导出</el-button>
                    </el-col>
                    <el-col :span="1.5">
                        <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
                    </el-col>
                    <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
                </el-row>
            </template>
            <el-table
                v-loading="loading"
                :data="productList"
                row-key="productId"
                :default-expand-all="isExpandAll"
                :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
                ref="productTableRef"
            >
                            <el-table-column label="产品名称" align="center" prop="productName" />
                            <el-table-column label="显示顺序" align="center" prop="orderNum" />
                        <el-table-column label="产品状态" align="center" prop="status">
                            <template #default="scope">
                                    <dict-tag :options="sys_student_status" :value="scope.row.status"/>
                            </template>
                        </el-table-column>
                <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
                    <template #default="scope">
                        <el-tooltip content="修改" placement="top">
                            <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['mf:product:edit']" />
                        </el-tooltip>
                        <el-tooltip content="新增" placement="top">
                            <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['mf:product:add']" />
                        </el-tooltip>
                        <el-tooltip content="删除" placement="top">
                            <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['mf:product:remove']" />
                        </el-tooltip>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>
        <!-- 添加或修改产品树对话框 -->
        <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
            <el-form ref="productFormRef" :model="form" :rules="rules" label-width="80px">
                            <el-form-item label="上级编号" prop="parentId">
                                <el-tree-select
                                    v-model="form.parentId"
                                    :data="productOptions"
                                    :props="{ value: 'productId', label: 'productName', children: 'children' }"
                                    value-key="productId"
                                    placeholder="请选择上级编号"
                                    check-strictly
                                />
                            </el-form-item>
                                <el-form-item label="产品名称" prop="productName">
                                    <el-input v-model="form.productName" placeholder="请输入产品名称" />
                                </el-form-item>
                                <el-form-item label="显示顺序" prop="orderNum">
                                    <el-input v-model="form.orderNum" placeholder="请输入显示顺序" />
                                </el-form-item>
                            <el-form-item label="产品状态" prop="status">
                                <el-radio-group v-model="form.status">
                                    <el-radio
                                        v-for="dict in sys_student_status"
                                        :key="dict.value"
                                        :label="dict.value"
                                    >{{dict.label}}</el-radio>
                                </el-radio-group>
                            </el-form-item>
                                <el-form-item label="乐观锁" prop="version" v-show="false">
                                    <el-input v-model="form.version" placeholder="请输入乐观锁" />
                                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
                    <el-button @click="cancel">取 消</el-button>
                </div>
            </template>
        </el-dialog>

        <!-- 导入对话框 -->
        <el-dialog v-model="upload.open" :title="upload.title" width="400px" append-to-body>
            <el-upload
                ref="uploadRef"
                :limit="1"
                accept=".xlsx, .xls"
                :headers="upload.headers"
                :action="upload.url + '?updateSupport=' + upload.updateSupport"
                :disabled="upload.isUploading"
                :on-progress="handleFileUploadProgress"
                :on-success="handleFileSuccess"
                :auto-upload="false"
                drag
            >
                <el-icon class="el-icon--upload">
                    <i-ep-upload-filled />
                </el-icon>
                <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
                <template #tip>
                    <div class="text-center el-upload__tip">
                        <div class="el-upload__tip">
                            <el-checkbox v-model="upload.updateSupport" />
                            是否更新已经存在的产品树数据
                        </div>
                        <span>仅允许导入xls、xlsx格式文件。</span>
                        <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板 </el-link>
                    </div>
                </template>
            </el-upload>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitFileForm">确 定</el-button>
                    <el-button @click="upload.open = false">取 消</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
    import { listProduct, getProduct, delProduct, addProduct, updateProduct } from "@/api/mf/product";
    import { ProductVO, ProductQuery, ProductForm } from '@/api/mf/product/types';
    import { globalHeaders } from '@/utils/request';

    type ProductOption = {
            productId: number;
            productName: string;
        children?: ProductOption[];
    };

    const { proxy } = getCurrentInstance() as ComponentInternalInstance;

    const { sys_student_status } = toRefs<any>(proxy?.useDict('sys_student_status'));

    const productList = ref<ProductVO[]>([]);
    const productOptions = ref<ProductOption[]>([]);
    const buttonLoading = ref(false);
    const showSearch = ref(true);
    const isExpandAll = ref(true);
    const loading = ref(false);

    const queryFormRef = ref<ElFormInstance>();
    const productFormRef = ref<ElFormInstance>();
    const productTableRef = ref<ElTableInstance>()
    const uploadRef = ref<ElUploadInstance>();

    /*** 导入参数 */
    const upload = reactive<ImportOption>({
        // 是否显示弹出层（导入）
        open: false,
        // 弹出层标题（导入）
        title: '',
        // 是否禁用上传
        isUploading: false,
        // 是否更新已经存在的用户数据
        updateSupport: 1,
        // 设置上传的请求头部
        headers: globalHeaders(),
        // 上传的地址
        url: import.meta.env.VITE_APP_BASE_API + '/mf/product/importData'
    });

    const dialog = reactive<DialogOption>({
        visible: false,
        title: ''
    });


    const initFormData: ProductForm = {
                            productId: undefined,
                            parentId: undefined,
                            productName: undefined,
                            orderNum: undefined,
                            status: undefined,
                            version: 0,
    };

    const data = reactive<PageData<ProductForm, ProductQuery>>({
        form: {...initFormData},
        queryParams: {
                            productName: undefined,
                            status: undefined,
            params: {
            }
        },
        rules: {
                            parentId: [
                            { required: true, message: "上级编号不能为空", trigger: "blur" }
                        ],
                            productName: [
                            { required: true, message: "产品名称不能为空", trigger: "blur" }
                        ],
                            orderNum: [
                            { required: true, message: "显示顺序不能为空", trigger: "blur" }
                        ],
                            status: [
                            { required: true, message: "产品状态不能为空", trigger: "change" }
                        ],
        }
    });

    const { queryParams, form, rules } = toRefs(data);

    /** 查询产品树列表 */
    const getList = async () => {
        loading.value = true;
        const res = await listProduct(queryParams.value);
        const data = proxy?.handleTree<ProductVO>(res.data, 'productId', 'parentId');
        if (data) {
                productList.value = data;
            loading.value = false;
        }
    };

    /** 查询产品树下拉树结构 */
    const getTreeselect = async () => {
        const res = await listProduct();
            productOptions.value = [];
        const data: ProductOption = { productId: 0, productName: '顶级节点', children: [] };
        data.children = proxy?.handleTree<ProductOption>(res.data, 'productId', 'parentId');
            productOptions.value.push(data);
    };

    // 取消按钮
    const cancel = () => {
        reset();
        dialog.visible = false;
    };

    // 表单重置
    const reset = () => {
        form.value = {...initFormData}
            productFormRef.value?.resetFields();
    };

    /** 搜索按钮操作 */
    const handleQuery = () => {
        getList();
    };

    /** 重置按钮操作 */
    const resetQuery = () => {
        queryFormRef.value?.resetFields();
        handleQuery();
    };

    /** 新增按钮操作 */
    const handleAdd = (row?: ProductVO) => {
        reset();
        getTreeselect();
        if (row != null && row.productId) {
            form.value.parentId = row.productId;
        } else {
            form.value.parentId = 0;
        }
        dialog.visible = true;
        dialog.title = '添加产品树';
    };

    /** 导出按钮操作 */
    const handleExport = () => {
        proxy?.download(
            'mf/product/export',
            {
                ...queryParams.value
            },
            `product.xlsx`
        );
    };

    /** 导入按钮操作 */
    const handleImport = () => {
        upload.title = '产品树导入';
        upload.open = true;
    };

    /** 下载模板操作 */
    const importTemplate = () => {
        proxy?.download('mf/product/importTemplate', {}, `product_template.xlsx`);
    };

    /**文件上传中处理 */
    const handleFileUploadProgress = () => {
        upload.isUploading = true;
    };
    /** 文件上传成功处理 */
    const handleFileSuccess = (response: any, file: UploadFile) => {
        upload.open = false;
        upload.isUploading = false;
        uploadRef.value?.handleRemove(file);
        ElMessageBox.alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + '</div>', '导入结果', {
            dangerouslyUseHTMLString: true
        });
        getList();
    };

    /** 提交上传文件 */
    function submitFileForm() {
        uploadRef.value?.submit();
    }

    /** 展开/折叠操作 */
    const handleToggleExpandAll = () => {
        isExpandAll.value = !isExpandAll.value;
        toggleExpandAll(productList.value, isExpandAll.value)
    };

    /** 展开/折叠操作 */
    const toggleExpandAll = (data: ProductVO[], status: boolean) => {
        data.forEach((item) => {
                productTableRef.value?.toggleRowExpansion(item, status)
            if (item.children && item.children.length > 0) toggleExpandAll(item.children, status)
        })
    };

    /** 修改按钮操作 */
    const handleUpdate = async (row: ProductVO) => {
        reset();
        await getTreeselect();
        if (row != null) {
            form.value.parentId = row.parentId;
        }
        const res = await getProduct(row.productId);
        Object.assign(form.value, res.data);
        dialog.visible = true;
        dialog.title = '修改产品树';
    };

    /** 提交按钮 */
    const submitForm = () => {
            productFormRef.value?.validate(async (valid: boolean) => {
            if (valid) {
                buttonLoading.value = true;
                if (form.value.productId) {
                    await updateProduct(form.value).finally(() => buttonLoading.value = false);
                } else {
                    await addProduct(form.value).finally(() => buttonLoading.value = false);
                }
                proxy?.$modal.msgSuccess('操作成功');
                dialog.visible = false;
                getList();
            }
        });
    };

    /** 删除按钮操作 */
    const handleDelete = async (row: ProductVO) => {
        await proxy?.$modal.confirm('是否确认删除产品树编号为"' + row.productId + '"的数据项？');
        loading.value = true;
        await delProduct(row.productId).finally(() => loading.value = false);
        await getList();
        proxy?.$modal.msgSuccess('删除成功');
    };

    onMounted(() => {
        getList();
    });
</script>
