<!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.nickName"
                            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>
                    <input
                            v-model="searchParams.username"
                            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.status"
                            class="form-select"
                            @change="fetchData()"
                    >
                        <option value="">全部状态</option>
                        <option value="1">启用</option>
                        <option value="0">禁用</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>状态</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.nickName }}</td>
                    <td>{{ item.username }}</td>
                    <td>{{ item.telephone }}</td>
                    <td>{{ item.email }}</td>
                    <td>
                        <span class="badge" :class="item.status === 1 ? 'bg-success' : 'bg-danger'">
                            {{ item.status === 1 ? '启用' : '禁用' }}
                        </span>
                    </td>
                    <td>{{ formatTime(item.createTime) }}</td>
                    <td>
                        <div class="d-flex gap-1">
                            <button class="btn btn-sm btn-warning" @click="openPwdModal(item)">
                                <i class="bi bi-lock"></i>
                            </button>
                            <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>
                    <option value="enable">批量启用</option>
                    <option value="disable">批量禁用</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>


<!-- 修改密码 -->
<div class="modal fade" id="resetPwdModal" tabindex="-1" aria-labelledby="resetPwdModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5" id="resetPwdModalLabel">修改密码</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-2 col-form-label">昵称</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" v-model="resetPasswordDto.nickName" disabled>
                        </div>
                    </div>

                    <div class="mb-3 row">
                        <label class="col-sm-2 col-form-label">用户名</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" v-model="resetPasswordDto.username" disabled>
                        </div>
                    </div>

                    <div class="mb-3 row">
                        <label class="col-sm-2 col-form-label">密码</label>
                        <div class="col-sm-10 position-relative">
                            <!-- 密码输入框 -->
                            <input :type="isPasswordVisible ? 'text' : 'password'" class="form-control pe-10"
                                   id="togglePassword"
                                   placeholder="请输入密码" v-model="resetPasswordDto.password">
                            <!-- 切换按钮（绝对定位在输入框右侧） -->
                            <button type="button"
                                    @click="togglePasswordVisibility"
                                    class="btn btn-transparent position-absolute end-0 top-0 h-100 px-3 border-0 bg-transparent"
                                    id="toggleBtn">
                                <i :class="isPasswordVisible ? 'bi bi-eye-slash text-secondary' : 'bi bi-eye text-secondary'"
                                   id="toggleIcon"></i>
                            </button>
                        </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="resetPwd">修改</button>
            </div>
        </div>
    </div>
</div>


<!-- 新增 or 编辑 -->
<div class="modal fade" id="addOrEditModel" tabindex="-1" aria-labelledby="addOrEditModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <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-2 col-form-label">昵称</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" v-model="addOrEditDto.nickName"
                                   placeholder="请输入昵称">
                        </div>
                    </div>
                    <div class="mb-3 row">
                        <label class="col-sm-2 col-form-label">用户名</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" v-model="addOrEditDto.username"
                                   placeholder="请输入用户名">
                        </div>
                    </div>
                    <div class="mb-3 row" v-if="addOrEditDto.id == null">
                        <label class="col-sm-2 col-form-label">密码</label>
                        <div class="col-sm-10">
                            <input type="password" class="form-control" v-model="addOrEditDto.password"
                                   placeholder="请输入密码">
                        </div>
                    </div>
                    <div class="mb-3 row">
                        <label class="col-sm-2 col-form-label">号码</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" v-model="addOrEditDto.telephone"
                                   placeholder="请输入号码">
                        </div>
                    </div>
                    <div class="mb-3 row">
                        <label class="col-sm-2 col-form-label">邮箱</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" v-model="addOrEditDto.email"
                                   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="saveUser">保存</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="/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: {
                    nickName: '',
                    username: '',
                    status: '',
                },
                pageNum: 1,
                pageSize: 10,
                total: 0,
                totalPages: 0,
                selectedIds: [],
                selectAll: false,
                batchAction: '',
                pageRange: 5,
                modalInstances: {},
                resetPasswordDto: {
                    userId: null,
                    nickName: null,
                    username: null,
                    password: null,
                },
                isPasswordVisible: false,
                addOrEditTitle: '',
                addOrEditDto: {
                    id: null,
                    username: null,
                    nickName: '',
                    password: null,
                    status: 1,
                    email: '',
                    telephone: ''
                }
            }
        },
        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 {
                    let start = Math.max(1, this.pageNum - 2);
                    let end = Math.min(this.totalPages, this.pageNum + 2);
                    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/user/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 = {
                    nickName: '',
                    username: '',
                    status: '',
                };
                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;
                    case 'enable':
                        this.handleBatchStatus(1);
                        break;
                    case 'disable':
                        this.handleBatchStatus(0);
                        break;
                }

                // 执行操作后重置选择
                this.batchAction = '';
            },

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

            // 批量修改状态（启用/禁用）
            async handleBatchStatus(status) {
                showConfirmModal({
                    title: '提示',
                    content: '确认更新这些数据吗？',
                    onConfirm: async () => {
                        try {
                            const response = await request.post('/biz/user/batchStatus', {
                                ids: this.selectedIds,
                                status: status
                            });
                            if (response.code === 200) {
                                $message.success(`已${status === 1 ? '启用' : '禁用'}选中数据！`);
                                this.fetchData();
                            }
                        } catch (error) {
                            console.error('批量更新状态失败:', error);
                            $message.error('操作失败，请重试！');
                        }
                    }
                });
            },

            // 单个删除
            async handleDelete(id) {
                showConfirmModal({
                    title: '删除确认',
                    content: '确定要删除这条数据吗？',
                    onConfirm: async () => {
                        try {
                            const response = await request.post('/biz/user/delete', {id});
                            if (response.code === 200) {
                                $message.success("删除成功");
                                this.fetchData(); // 重新加载数据
                            }
                        } catch (error) {
                            console.error('删除失败:', error);
                            $message.error('删除失败，请重试！');
                        }
                    }
                });
            },
            // 打开重置密码墨台框
            openPwdModal(item) {
                console.log(item)
                this.resetPasswordDto.userId = item.id;
                this.resetPasswordDto.username = item.username;
                this.resetPasswordDto.nickName = item.nickName;
                this.resetPasswordDto.password = '';
                this.modalInstances['resetPwdModal'].show();
            },
            resetPwd() {
                request.put("/biz/user/resetPasswordRequest", this.resetPasswordDto)
                    .then((res) => {
                        if (res.code === 200) {
                            $message.success('修改成功！', 500);
                            this.modalInstances['resetPwdModal'].hide();
                        } else {
                            $message.error('修改失败，请重试！');
                        }
                        this.resetPasswordDto = {};
                    }).catch((error) => {
                    $message.error('修改失败，请重试！');
                })

            },
            // 打开新增模态框
            openAddModal() {
                this.addOrEditTitle = '新增';
                this.clearForm();
                this.modalInstances['addOrEditModel'].show();
            },

            // 打开编辑模态框
            openEditModal(item) {
                this.clearForm();
                this.addOrEditTitle = '编辑';
                this.addOrEditDto = item;
                this.modalInstances['addOrEditModel'].show();
            },
            saveUser() {
                let url = (this.addOrEditDto === null || this.addOrEditDto.id === null) ? '/biz/user/save' : '/biz/user/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(() => {

                })
            },
            togglePasswordVisibility() {
                this.isPasswordVisible = !this.isPasswordVisible;
            },
            // 清空表单数据
            clearForm() {
                this.addOrEditDto = {
                    id: null,
                    username: null,
                    nickName: '',
                    password: null,
                    status: 1,
                    email: '',
                    telephone: ''
                };
            }

        },
        mounted() {
            this.fetchData();
            const modalIds = ['resetPwdModal', 'addOrEditModel'];
            modalIds.forEach(id => {
                console.log(id)
                const modalElement = document.getElementById(id);
                if (modalElement) {
                    this.modalInstances[id] = new bootstrap.Modal(modalElement, {
                        backdrop: 'static',
                        keyboard: true
                    });
                }
            });
        }
    }).mount('#app');
</script>
</body>
</html>
