<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>隐私政策</title>
    <!-- 外部引入库文件 -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
    <!-- 外部引入自定义样式 -->
    <link rel="stylesheet" href="/assets/css/table.css">
</head>
<body id="app">
<div class="main-container">
    <div class="table-container">
        <h4 class="mb-3">隐私政策</h4>

        <div class="search-bar">
            <div class="search-item">
                <div class="input-group">
                    <span class="input-group-text">
                        名称
                    </span>
                    <input
                            v-model="searchParams.title"
                            type="text"
                            class="form-control"
                            placeholder="请输入名称"
                            @keyup.enter="fetchData()"
                    >
                </div>
            </div>

            <div class="search-item">
                <div class="input-group">
                    <span class="input-group-text">
                       是否显示
                    </span>
                    <select
                            v-model="searchParams.visible"
                            class="form-select"
                            @change="fetchData()"
                    >
                        <option value="">全部状态</option>
                        <option value="1">显示</option>
                        <option value="2">隐藏</option>
                    </select>
                </div>
            </div>

            <div class="d-flex gap-2">
                <button class="btn btn-primary" @click="fetchData()">
                    <i class="bi bi-search me-1"></i> 搜索
                </button>
                <button class="btn btn-success" @click="resetSearch()">
                    <i class="bi bi-arrow-counterclockwise me-1"></i> 重置
                </button>
            </div>
        </div>

        <div class="mb-2">
            <button class="btn btn-info" @click="openAddModal()">
                <i class="bi bi-plus-circle me-1"></i> 新增
            </button>
        </div>

        <div class="table-responsive">
            <table class="table table-sm table-striped table-hover table-bordered ">
                <thead class="table-light">
                <tr>
                    <!-- 全选复选框 -->
                    <th style="width: 50px;">
                        <input
                                type="checkbox"
                                class="form-check-input"
                                v-model="selectAll"
                                @change="toggleSelectAll()"
                        >
                    </th>
                    <th>名称</th>
                    <th>是否显示</th>
                    <th>排序</th>
                    <th>创建时间</th>
                    <th style="width: 120px;">操作</th>
                </tr>
                </thead>
                <tbody>
                <!-- 加载中状态 -->
                <tr v-if="loading">
                    <td colspan="8" class="p-0">
                        <div class="loading-container">
                            <div class="spinner-border text-primary" role="status" style="width: 2rem; height: 2rem;">
                                <span class="visually-hidden">Loading...</span>
                            </div>
                            <p class="mt-2 text-muted">加载中，请稍候...</p>
                        </div>
                    </td>
                </tr>

                <!-- 无数据状态 -->
                <tr v-else-if="tableData.length === 0">
                    <td colspan="8" class="p-0">
                        <div class="no-data">
                            <i class="bi bi-folder-x"></i>
                            <h5>暂无匹配数据</h5>
                            <p class="text-muted">请尝试调整搜索条件或重置查询</p>
                        </div>
                    </td>
                </tr>

                <!-- 数据列表 -->
                <tr v-else v-for="(item, index) in tableData" :key="item.id"
                    :class="{ selected: selectedIds.includes(item.id) }">
                    <td>
                        <input
                                type="checkbox"
                                class="form-check-input"
                                v-model="selectedIds"
                                :value="item.id"
                                @change="toggleSelectItem(item.id)"
                        >
                    </td>
                    <td>{{ item.title }}</td>
                    <td>
                        <span class="badge" :class="item.visible === 1 ? 'bg-success' : 'bg-danger'">
                            {{ item.visible === 1 ? '启用' : '禁用' }}
                        </span>
                    </td>
                    <td>{{ item.sort }}</td>
                    <td>{{ formatTime(item.createTime) }}</td>
                    <td>
                        <div class="d-flex gap-1">
                            <button class="btn btn-sm btn-primary" @click="openEditModal(item)">
                                <i class="bi bi-pencil"></i>
                            </button>
                            <button class="btn btn-sm btn-danger" @click="handleDelete(item.id)">
                                <i class="bi bi-trash"></i>
                            </button>
                        </div>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>

        <div class="batch-actions mt-3">
            <div class="d-flex align-items-center gap-2">
                <span class="text-muted">已选中 {{ selectedIds.length }} 条数据</span>
                <select
                        class="form-select"
                        v-model="batchAction"
                        :disabled="selectedIds.length === 0"
                        @change="handleBatchOperation"
                        style="width: auto; min-width: 160px;"
                >
                    <option value="">-- 批量操作 --</option>
                    <option value="delete">批量删除</option>
                </select>

                <button
                        class="btn btn-secondary"
                        @click="clearSelected()"
                        :disabled="selectedIds.length === 0"
                >
                    <i class="bi bi-x-circle me-1"></i> 取消选择
                </button>
            </div>
        </div>

        <div class="d-flex justify-content-between align-items-center mt-3">
            <div class="page-info">
                共 {{ total }} 条数据，当前第 {{ pageNum }}/{{ totalPages }} 页
            </div>
            <nav>
                <ul class="pagination pagination-sm mb-0">
                    <li class="page-item" :class="{ disabled: pageNum === 1 }">
                        <a class="page-link" href="#" @click.prevent="changePage(1)">首页</a>
                    </li>
                    <li class="page-item" :class="{ disabled: pageNum === 1 }">
                        <a class="page-link" href="#" @click.prevent="changePage(pageNum - 1)">上一页</a>
                    </li>
                    <li class="page-item" :class="page === pageNum ? 'active' : ''" v-for="page in pageList"
                        :key="page">
                        <a class="page-link" href="#" @click.prevent="changePage(page)">{{ page }}</a>
                    </li>
                    <li class="page-item" :class="{ disabled: pageNum === totalPages }">
                        <a class="page-link" href="#" @click.prevent="changePage(pageNum + 1)">下一页</a>
                    </li>
                    <li class="page-item" :class="{ disabled: pageNum === totalPages }">
                        <a class="page-link" href="#" @click.prevent="changePage(totalPages)">末页</a>
                    </li>
                </ul>
            </nav>
        </div>
    </div>


</div>



<!-- 新增 or 编辑 -->
<div class="modal fade" id="addOrEditModel" tabindex="-1" aria-labelledby="addOrEditModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5" id="addOrEditModalLabel">{{ addOrEditTitle }}</h1>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <form>
                    <div class="mb-3 row">
                        <label class="col-sm-3 col-form-label">名称</label>
                        <div class="col-sm-9">
                            <input type="text" class="form-control" v-model="addOrEditDto.title"
                                   placeholder="请输入名称">
                        </div>
                    </div>
                    <div class="mb-3 row">
                        <label class="col-sm-3 col-form-label">内容</label>
                        <div class="col-sm-9">
                            <!-- 富文本编辑器容器 -->
                            <div id="contentEditor" style="border: 1px solid #dee2e6; border-radius: 0.375rem;"></div>
                            <!-- 错误提示 -->
                            <div class="invalid-feedback" id="contentError" style="display: none; margin-top: 0.25rem;"></div>
                        </div>
                    </div>
                    <div class="mb-3 row">
                        <label class="col-sm-3 col-form-label">是否显示</label>
                        <div class="col-sm-9">
                            <select class="form-control" v-model="addOrEditDto.visible">
                                <option value=1>显示</option>
                                <option value=2>隐藏</option>
                            </select>
                        </div>
                    </div>
                    <div class="mb-3 row">
                        <label class="col-sm-3 col-form-label">序号</label>
                        <div class="col-sm-9">
                            <input type="number" class="form-control" v-model="addOrEditDto.sort"
                                   placeholder="请输入序号">
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
                <button type="button" class="btn btn-primary" @click.prevent="saveEntity">保存</button>
            </div>
        </div>
    </div>
</div>

<!-- 外部引入库文件 -->
<script src="https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@1.4.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://unpkg.com/wangeditor@4.7.15/dist/wangEditor.min.js"></script>
<!-- 外部引入模拟请求文件 -->
<script src="/assets/js/axiosRequest.js"></script>
<script src="/assets/js/message.js"></script>
<script src="/assets/js/confirmModal.js"></script>

<!-- 页面核心逻辑 -->
<script>
    const {createApp} = Vue;

    createApp({
        data() {
            return {
                tableData: [], // 表格数据源
                loading: false, // 加载状态
                searchParams: {
                    title: '',
                    visible: '',
                },
                // 分页参数
                pageNum: 1, // 当前页码
                pageSize: 10, // 每页条数
                total: 0, // 总数据量
                totalPages: 0, // 总页数
                // 批量操作
                selectedIds: [], // 选中的ID集合
                selectAll: false, // 全选状态
                batchAction: '', // 批量操作选择
                pageRange: 5,
                modalInstances: {},
                resetPasswordDto: {
                    userId: null,
                    nickName: null,
                    username: null,
                    password: null,
                },
                addOrEditTitle: '',
                addOrEditDto: {
                    id: null,
                    title: null,
                    content: null,
                    visible: 1,
                    sort: 99
                },
                editor: null, // WangEditor 实例
            }
        },
        computed: {
            // 计算当前显示的页码列表
            pageList() {
                const list = [];
                if (this.totalPages === 0) return list;

                // 总页数小于等于显示范围，直接显示所有页码
                if (this.totalPages <= this.pageRange) {
                    for (let i = 1; i <= this.totalPages; i++) {
                        list.push(i);
                    }
                } else {
                    // 总页数大于显示范围，显示当前页前后2个页码
                    let start = Math.max(1, this.pageNum - 2);
                    let end = Math.min(this.totalPages, this.pageNum + 2);

                    // 确保显示5个页码
                    if (end - start < this.pageRange - 1) {
                        if (start === 1) {
                            end = this.pageRange;
                        } else if (end === this.totalPages) {
                            start = this.totalPages - this.pageRange + 1;
                        }
                    }

                    for (let i = start; i <= end; i++) {
                        list.push(i);
                    }
                }
                return list;
            }
        },
        methods: {
            formatTime(time) {
                if (!time) return '-';
                const date = new Date(time);
                return date.toLocaleString('zh-CN', {
                    year: 'numeric',
                    month: '2-digit',
                    day: '2-digit',
                    hour: '2-digit',
                    minute: '2-digit',
                    second: '2-digit'
                });
            },

            async fetchData() {
                this.loading = true;
                try {
                    const response = await request.get('/biz/privacy_policy/page', {
                        ...this.searchParams,
                        current: this.pageNum,
                        size: this.pageSize
                    });
                    console.log(response)

                    if (response.code === 200) {
                        this.tableData = response.data.records; // 列表数据
                        this.total = response.data.total; // 总条数
                        this.totalPages = response.data.pages; // 总页数
                    }
                } catch (error) {
                    console.error('获取数据失败:', error);
                    this.tableData = [];
                    this.total = 0;
                    this.totalPages = 0;
                } finally {
                    this.loading = false;
                    this.clearSelected();
                }
            },

            // 切换页码
            changePage(page) {
                if (page < 1 || page > this.totalPages || page === this.pageNum) return;
                this.pageNum = page;
                this.fetchData();
            },

            // 重置搜索
            resetSearch() {
                this.searchParams = {
                    title: '',
                    visible: '',
                };
                this.pageNum = 1;
                this.fetchData();
            },

            // 全选/取消全选
            toggleSelectAll() {
                if (this.selectAll) {
                    this.selectedIds = this.tableData.map(item => item.id);
                } else {
                    this.selectedIds = [];
                }
            },

            // 单个选中/取消选中
            toggleSelectItem(id) {
                this.selectAll = this.selectedIds.length === this.tableData.length && this.tableData.length > 0;
            },

            // 清空选中状态
            clearSelected() {
                this.selectedIds = [];
                this.selectAll = false;
                this.batchAction = '';
            },

            // 处理批量操作
            handleBatchOperation() {
                if (!this.batchAction || this.selectedIds.length === 0) return;

                switch (this.batchAction) {
                    case 'delete':
                        this.handleBatchDelete();
                        break;
                }

                this.batchAction = '';
            },

            // 批量删除
            async handleBatchDelete() {
                showConfirmModal({
                    title: '删除确认',
                    content: `确定要删除选中的 ${this.selectedIds.length} 条数据吗？`,
                    onConfirm: async () => {
                        try {
                            const response = await request.post('/biz/privacy_policy/batchDelete', {ids: this.selectedIds});
                            if (response.code === 200) {
                                $message.success("删除成功");
                                this.fetchData();
                            }
                        } catch (error) {
                            console.error('删除失败:', error);
                            $message.error('删除失败，请重试！');
                        }
                    }
                });
            },

            // 单个删除
            async handleDelete(id) {
                showConfirmModal({
                    title: '删除确认',
                    content: '确定要删除这条数据吗？',
                    onConfirm: async () => {
                        try {
                            const response = await request.delete('/biz/privacy_policy/delete', {id});
                            if (response.code === 200) {
                                $message.success("删除成功");
                                this.fetchData(); // 重新加载数据
                            }
                        } catch (error) {
                            console.error('删除失败:', error);
                            $message.error('删除失败，请重试！');
                        }
                    }
                });
            },
            // 打开新增模态框
            openAddModal() {
                this.addOrEditTitle = '新增';
                this.clearForm();
                this.modalInstances['addOrEditModel'].show();
            },

            // 打开编辑模态框
            openEditModal(item) {
                this.addOrEditTitle = '编辑';
                this.addOrEditDto = {...item};
                // 延迟回显富文本内容
                setTimeout(() => {
                    if (this.editor) this.editor.txt.html(item.content || '');
                }, 300);
                this.modalInstances['addOrEditModel'].show();
            },
            saveEntity() {
                let url = (this.addOrEditDto === null || this.addOrEditDto.id === null) ? '/biz/privacy_policy/save' : '/biz/privacy_policy/update';
                request.post(url, this.addOrEditDto)
                    .then((res) => {
                        if (res.code === 200) {
                            $message.success('保存成功！', 500);
                            this.fetchData();
                            this.modalInstances['addOrEditModel'].hide();
                        } else {
                            $message.error('保存失败！', 500);
                        }
                        this.clearForm();

                    }).catch(() => {

                })
            },
            // 清空表单数据
            clearForm() {
                this.addOrEditDto = {
                    id: null,
                    title: null,
                    content: null,
                    visible: 1,
                    sort: 99
                };
            },
            // 初始化 WangEditor
            initWangEditor() {
                const _this = this;
                // 获取编辑器容器
                const editorDom = document.getElementById('contentEditor');
                // 创建编辑器实例
                this.editor = new wangEditor(editorDom);

                // 编辑器配置
                this.editor.config.height = 200; // 高度
                this.editor.config.zIndex = 1050; // 层级（确保在模态框上方）
                this.editor.config.uploadImgShowBase64 = true; // 图片以 Base64 格式保存（无需后端接口）
                this.editor.config.menus = [
                    'head', // 标题
                    'bold', // 粗体
                    'italic', // 斜体
                    'underline', // 下划线
                    'strikeThrough', // 删除线
                    'foreColor', // 文字颜色
                    'backColor', // 背景颜色
                    'link', // 插入链接
                    'list', // 列表
                    'justify', // 对齐方式
                    'image', // 插入图片
                    'table', // 表格
                    'code', // 插入代码
                    'undo', // 撤销
                    'redo' // 重做
                ];

                // 内容变化时同步到 Vue 数据
                this.editor.config.onchange = function (html) {
                    _this.addOrEditDto.content = html;
                };

                // 创建编辑器
                this.editor.create();
            },
        },
        mounted() {
            this.fetchData();
            const modalIds = ['uploadFileModal', 'addOrEditModel'];
            modalIds.forEach(id => {
                const modalElement = document.getElementById(id);
                if (modalElement) {
                    this.modalInstances[id] = new bootstrap.Modal(modalElement, {
                        backdrop: 'static',
                        keyboard: true
                    });
                }
            });

            // 初始化 WangEditor（延迟初始化，确保DOM加载完成）
            setTimeout(() => {
                this.initWangEditor();
            }, 500);

            // 监听模态框关闭事件，避免内存泄漏
            const modal = document.getElementById('addOrEditModel');
            modal.addEventListener('hidden.bs.modal', () => {
                if (this.editor) {
                    this.editor.txt.clear(); // 清空内容
                    document.getElementById('contentEditor').style.borderColor = '#dee2e6';
                    document.getElementById('contentError').style.display = 'none';
                }
            });
        }
    }).mount('#app');
</script>
</body>
</html>
