<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>前台用户管理</title>
    <link rel="stylesheet" href="{{ asset('CmsProUi/component/pear/css/pear.css') }}">
    <link rel="stylesheet" href="{{ asset('CmsProUi/font-awesome/4.7.0/css/font-awesome.min.css') }}">
    <link rel="stylesheet" href="{{ asset('Admin/css/admin.css') }}">
    <link rel="stylesheet" href="{{ asset('Admin/css/variables.css') }}">
    <link rel="stylesheet" href="{{ asset('Admin/css/reset.css') }}">
    <style>
    .layui-table img {
        max-width: 30px;
        padding: 6px;
        border-radius: 50%;
    }
    .user-info {
        display: flex;
        align-items: center;
        gap: 8px;
    }
    .user-info .user-detail {
        text-align: left;
        line-height: 1.4;
    }
    .user-info .user-detail .username {
        font-weight: 500;
    }
    .user-info .user-detail .nickname {
        font-size: 12px;
        color: #999;
    }
    </style>
    @include('admin.partials.permission-script')
</head>
<body>
<div class="pear-container">
    <div class="layui-card">
        <div class="layui-card-body">
            <form class="layui-form" action="">
                <div class="layui-inline">
                    <div class="layui-input-inline">
                        <input type="text" name="keyword" placeholder="用户名/昵称/邮箱/手机" class="layui-input">
                    </div>
                </div>
                <div class="layui-inline">
                    <div class="layui-input-inline">
                        <select name="group_id" id="group-filter">
                            <option value="">全部用户组</option>
                        </select>
                    </div>
                </div>
                <div class="layui-inline">
                    <div class="layui-input-inline">
                        <select name="status">
                            <option value="">全部状态</option>
                            <option value="1">正常</option>
                            <option value="0">禁用</option>
                        </select>
                    </div>
                </div>
                <div class="layui-inline">
                    <button class="layui-btn layui-btn-md" lay-submit lay-filter="user-query">
                        <i class="layui-icon layui-icon-search"></i> 查询
                    </button>
                    <button type="reset" class="layui-btn layui-btn-md layui-btn-primary">
                        <i class="layui-icon layui-icon-refresh"></i> 重置
                    </button>
                </div>
                <div class="layui-inline" style="float: right;" id="btn-ext-fields-wrap" hidden>
                    <button type="button" class="layui-btn layui-btn-md layui-btn-normal" id="btn-ext-fields">
                        <i class="layui-icon layui-icon-app"></i> 扩展管理
                    </button>
                </div>
            </form>
        </div>
    </div>

    <div class="layui-card">
        <div class="layui-card-body">
            <table id="user-table" lay-filter="user-table"></table>
        </div>
    </div>

    <script type="text/html" id="user-toolbar">
        <button class="layui-btn layui-btn-sm" lay-event="add" data-permission="admin.front-user.store">
            <i class="layui-icon layui-icon-add-1"></i> 新增
        </button>
        <button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="batchRemove" data-permission="admin.front-user.batch-delete">
            <i class="layui-icon layui-icon-delete"></i> 批量删除
        </button>
    </script>

    @verbatim
    <script type="text/html" id="user-info-tpl">
        <div class="user-info">
            <img src="{{ d.avatar || '/Admin/images/avatar.png' }}" alt="">
            <div class="user-detail">
                <div class="username">{{ d.username }}</div>
                <div class="nickname">{{ d.nickname || '-' }}</div>
            </div>
        </div>
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="user-group-tpl">
        {{# if(d.group){ }}
        <span class="layui-badge" style="background-color:{{ d.group.color || '#5FB878' }}">{{ d.group.name }}</span>
        {{# } else { }}
        -
        {{# } }}
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="user-status-tpl">
        <input type="checkbox" name="status" value="{{ d.id }}" lay-skin="switch" lay-text="正常|禁用" lay-filter="user-status" {{ d.status == 1 ? 'checked' : '' }} />
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="user-last-login-tpl">
        <span>{{# if(d.last_login_at){ }}{{ d.last_login_at }}{{# } else { }}-{{# } }}</span>
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="ext-field-type-tpl">
        {{# var typeMap = {text:'文本',number:'数字',select:'下拉选择',textarea:'多行文本',switch:'开关',date:'日期',json:'JSON'}; }}
        <span>{{ typeMap[d.field_type] || d.field_type }}</span>
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="ext-field-status-tpl">
        <input type="checkbox" name="ext_status" value="{{ d.id }}" lay-skin="switch" lay-text="启用|禁用" lay-filter="ext-field-status" {{ d.status == 1 ? 'checked' : '' }} />
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="ext-field-bar">
        <div class="layui-btn-container">
            <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
            <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
        </div>
    </script>
    @endverbatim

    <script type="text/html" id="user-bar">
        <div class="layui-btn-container">
            <a class="layui-btn layui-btn-xs" lay-event="more">操作 <i class="layui-icon layui-icon-down"></i></a>
        </div>
    </script>
</div>
<script src="{{ asset('CmsProUi/component/layui/layui.js') }}"></script>
<script src="{{ asset('CmsProUi/component/pear/pear.js') }}"></script>
<script>
    layui.use(['table', 'form', 'jquery', 'common', 'dropdown'], function() {
        var table = layui.table;
        var form = layui.form;
        var $ = layui.jquery;
        var dropdown = layui.dropdown;

        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': '{{ csrf_token() }}'
            },
            statusCode: {
                401: function() {
                    layer.msg('登录已过期，请重新登录', {icon: 2, time: 1500}, function() {
                        window.location.href = '/admin/login?redirect=' + encodeURIComponent(window.location.pathname + window.location.search);
                    });
                }
            }
        });

        // 根据权限隐藏工具栏按钮
        $('#user-toolbar [data-permission]').each(function() {
            if (!window.hasPermission || !window.hasPermission($(this).data('permission'))) {
                $(this).hide();
            }
        });

        // 扩展管理按钮仅超管/创始人可见（扩展字段为全局配置，影响所有前台用户）
        if (window.CMSPRO_PERMISSIONS && window.CMSPRO_PERMISSIONS.indexOf('*') !== -1) {
            $('#btn-ext-fields-wrap').prop('hidden', false);
        }

        var groupOptions = [];
        $.ajax({
            url: '/api/admin/user-groups/all',
            type: 'GET',
            async: false,
            success: function(res) {
                if (res.code === 0 && res.data) {
                    groupOptions = res.data;
                    var html = '<option value="">全部用户组</option>';
                    for (var i = 0; i < groupOptions.length; i++) {
                        html += '<option value="' + groupOptions[i].id + '">' + groupOptions[i].name + '</option>';
                    }
                    $('#group-filter').html(html);
                    form.render('select');
                }
            }
        });

        var cols = [[
            { type: 'checkbox', fixed: 'left' },
            { title: 'ID', field: 'id', align: 'center', width: 80, sort: true },
            { title: '用户信息', field: 'username', align: 'center', minWidth: 140, templet: '#user-info-tpl' },
            { title: '邮箱', field: 'email', align: 'center', minWidth: 160 },
            { title: '手机号', field: 'phone', align: 'center', width: 130 },
            { title: '用户组', field: 'group', align: 'center', width: 110, templet: '#user-group-tpl' },
            { title: '状态', field: 'status', align: 'center', width: 110, templet: '#user-status-tpl' },
            { title: '登录次数', field: 'login_count', align: 'center', width: 100, sort: true },
            { title: '最后登录', field: 'last_login_at', align: 'center', width: 170, templet: '#user-last-login-tpl' },
            { title: '操作', toolbar: '#user-bar', align: 'center', width: 100, fixed: 'right' }
        ]];

        var inst = table.render({
            elem: '#user-table',
            url: '/api/admin/front-users',
            page: {
                layout: ['count', 'prev', 'page', 'next', 'limit'],
                groups: 5,
                limit: 20,
                limits: [10, 20, 50, 100]
            },
            cols: cols,
            skin: false,
            toolbar: '#user-toolbar',
            defaultToolbar: [{
                title: '刷新',
                layEvent: 'refresh',
                icon: 'layui-icon-refresh'
            }, 'filter', 'print', 'exports'],
            parseData: function(res) {
                return {
                    "code": res.code === 0 ? 0 : 1,
                    "msg": res.message || "",
                    "count": res.data && res.data.pagination ? res.data.pagination.total : 0,
                    "data": res.data ? res.data.items : []
                };
            }
        });

        form.on('submit(user-query)', function(data) {
            table.reload('user-table', { where: data.field, page: { curr: 1 } });
            return false;
        });

        form.on('switch(user-status)', function(obj) {
            if (!window.hasPermission || !window.hasPermission('admin.front-user.status')) {
                $(obj.elem).prop('checked', !obj.elem.checked);
                form.render();
                layer.msg('无操作权限', { icon: 2, time: 1000 });
                return;
            }
            var id = this.value;
            $.ajax({
                url: '/api/admin/front-users/' + id + '/status',
                type: 'PUT',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify({ status: obj.elem.checked ? 1 : 0 }),
                success: function(res) {
                    if (res.code === 0) {
                        layer.msg('状态更新成功', { icon: 1, time: 1000 });
                    } else {
                        layer.msg(res.message || '操作失败', { icon: 2, time: 1000 });
                        $(obj.elem).prop('checked', !obj.elem.checked);
                        form.render();
                    }
                },
                error: function() {
                    layer.msg('请求失败', { icon: 2, time: 1000 });
                    $(obj.elem).prop('checked', !obj.elem.checked);
                    form.render();
                }
            });
        });

        table.on('toolbar(user-table)', function(obj) {
            if (obj.event === 'add') {
                window.add();
            } else if (obj.event === 'refresh') {
                table.reload('user-table');
            } else if (obj.event === 'batchRemove') {
                window.batchRemove(obj);
            }
        });

        table.on('tool(' + inst.config.id + ')', function(obj) {
            if (obj.event === 'more') {
                var menuData = [
                    { title: '编辑', id: 'edit', permission: 'admin.front-user.update' },
                    { title: '重置密码', id: 'resetPwd', permission: 'admin.front-user.reset-password' },
                    { title: '删除', id: 'del', permission: 'admin.front-user.destroy' }
                ];
                // 根据权限过滤菜单项
                if (window.hasPermission) {
                    menuData = menuData.filter(function(item) {
                        return window.hasPermission(item.permission);
                    });
                }
                if (menuData.length === 0) return;
                dropdown.render({
                    elem: this,
                    show: true,
                    align: 'right',
                    data: menuData,
                    click: function(menudata) {
                        if (menudata.id === 'edit') {
                            window.edit(obj);
                        } else if (menudata.id === 'resetPwd') {
                            window.resetPassword(obj);
                        } else if (menudata.id === 'del') {
                            window.remove(obj);
                        }
                    }
                });
            }
        });

        // 双击行查看用户详情
        table.on('rowDouble(' + inst.config.id + ')', function(obj) {
            window.viewDetail(obj.data.id);
        });

        // 查看用户详情弹窗
        window.viewDetail = function(id) {
            var loading = layer.load();
            // 并发拉取用户详情 + 扩展字段定义（用于显示扩展字段 label）
            var userReq = $.ajax({ url: '/api/admin/front-users/' + id, type: 'GET', dataType: 'json' });
            var extReq = $.ajax({ url: '/api/admin/user-ext-fields', type: 'GET', dataType: 'json' });
            $.when(userReq, extReq).done(function(userRes, extRes) {
                layer.close(loading);
                userRes = userRes[0];
                extRes = extRes[0];
                if (userRes.code === 0 && userRes.data) {
                    var extDefs = (extRes.code === 0 && extRes.data) ? extRes.data : [];
                    showUserDetail(userRes.data, extDefs);
                } else {
                    layer.msg(userRes.message || '获取用户信息失败', { icon: 2 });
                }
            }).fail(function() {
                layer.close(loading);
                layer.msg('请求失败', { icon: 2 });
            });
        };

        function escapeHtml(str) {
            if (str === null || str === undefined) return '';
            return String(str).replace(/[&<>"']/g, function(s) {
                return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[s];
            });
        }

        function showUserDetail(d, extDefs) {
            // 构建扩展字段 label 映射 + 静态 select 选项 label 映射
            var extLabelMap = {};
            var extOptionMap = {};
            for (var i = 0; i < extDefs.length; i++) {
                var f = extDefs[i];
                extLabelMap[f.field_name] = f.field_label;
                if (f.field_type === 'select' && Array.isArray(f.field_options)) {
                    var optMap = {};
                    for (var j = 0; j < f.field_options.length; j++) {
                        optMap[f.field_options[j].value] = f.field_options[j].label;
                    }
                    extOptionMap[f.field_name] = optMap;
                }
            }

            // 性别文案
            var genderText = '未知';
            if (d.gender == 1) genderText = '男';
            else if (d.gender == 2) genderText = '女';

            var html = '<div>';

            // 基本信息区
            html += '<fieldset class="layui-elem-field"><legend>基本信息</legend><div class="layui-field-box">';
            html += '<table class="layui-table" lay-size="sm" style="margin:0;">';
            html += '<colgroup><col width="120"><col></colgroup>';
            html += '<tr><td>用户名</td><td>' + escapeHtml(d.username) + '</td></tr>';
            html += '<tr><td>昵称</td><td>' + escapeHtml(d.nickname || '-') + '</td></tr>';
            html += '<tr><td>邮箱</td><td>' + escapeHtml(d.email || '-') + '</td></tr>';
            html += '<tr><td>手机号</td><td>' + escapeHtml(d.phone || '-') + '</td></tr>';
            html += '<tr><td>性别</td><td>' + genderText + '</td></tr>';
            html += '<tr><td>生日</td><td>' + escapeHtml(d.birthday || '-') + '</td></tr>';
            html += '<tr><td>用户组</td><td>' + (d.group ? escapeHtml(d.group.name) : '-') + '</td></tr>';
            html += '<tr><td>状态</td><td>' + (d.status == 1
                ? '<span class="layui-badge layui-bg-green">正常</span>'
                : '<span class="layui-badge layui-bg-gray">禁用</span>') + '</td></tr>';
            html += '<tr><td>登录次数</td><td>' + (d.login_count || 0) + '</td></tr>';
            html += '<tr><td>最后登录</td><td>' + escapeHtml(d.last_login_at || '从未登录') + '</td></tr>';
            html += '<tr><td>最后登录IP</td><td>' + escapeHtml(d.last_login_ip || '-') + '</td></tr>';
            if (d.signature) {
                html += '<tr><td>签名</td><td>' + escapeHtml(d.signature) + '</td></tr>';
            }
            html += '<tr><td>创建时间</td><td>' + escapeHtml(d.create_time || '-') + '</td></tr>';
            html += '<tr><td>更新时间</td><td>' + escapeHtml(d.update_time || '-') + '</td></tr>';
            html += '</table>';
            html += '</div></fieldset>';

            // 扩展字段信息
            if (d.ext_fields && Object.keys(d.ext_fields).length > 0) {
                html += '<fieldset class="layui-elem-field"><legend>扩展信息</legend><div class="layui-field-box">';
                html += '<table class="layui-table" lay-size="sm" style="margin:0;">';
                html += '<colgroup><col width="120"><col></colgroup>';
                // 收集动态数据源字段，渲染后异步拉取并替换显示值
                var dynamicFields = [];
                for (var key in d.ext_fields) {
                    if (!d.ext_fields.hasOwnProperty(key)) continue;
                    var val = d.ext_fields[key];
                    var displayVal = val;
                    var extDef = null;
                    for (var i = 0; i < extDefs.length; i++) {
                        if (extDefs[i].field_name === key) { extDef = extDefs[i]; break; }
                    }
                    var isMultiple = extDef && extDef.field_options && extDef.field_options.multiple === true;
                    if (isMultiple && Array.isArray(val)) {
                        // 多选字段：逐个映射 label
                        var labels = [];
                        for (var vi = 0; vi < val.length; vi++) {
                            var v = val[vi];
                            if (extOptionMap[key] && extOptionMap[key][v]) {
                                labels.push(extOptionMap[key][v]);
                            } else {
                                labels.push(v);
                            }
                        }
                        displayVal = labels.join('、');
                    } else {
                        if (extOptionMap[key] && val !== null && val !== '' && extOptionMap[key][val]) {
                            displayVal = extOptionMap[key][val];
                        }
                    }
                    if (displayVal === null || displayVal === '' || displayVal === undefined) {
                        displayVal = '-';
                    }
                    var cellId = '';
                    if (extDef && extDef.field_type === 'select'
                        && extDef.field_options && extDef.field_options.source) {
                        cellId = ' id="ext-detail-' + key + '"';
                        dynamicFields.push({
                            name: key,
                            value: val,
                            source: extDef.field_options.source
                        });
                    }
                    html += '<tr><td>' + escapeHtml(extLabelMap[key] || key) + '</td><td' + cellId + '>' + escapeHtml(displayVal) + '</td></tr>';
                }
                html += '</table>';
                html += '</div></fieldset>';

                // 异步拉取动态数据源，替换 ID 为 label
                dynamicFields.forEach(function(item) {
                    $.ajax({
                        url: item.source.url,
                        type: 'GET',
                        dataType: 'json',
                        success: function(res) {
                            if (res.code === 0 && res.data) {
                                var list = Array.isArray(res.data) ? res.data : (res.data.items || []);
                                var $cell = $('#ext-detail-' + item.name);
                                if (!$cell.length) return;
                                if (Array.isArray(item.value)) {
                                    // 多选：映射多个 label
                                    var labels = [];
                                    for (var idx = 0; idx < item.value.length; idx++) {
                                        for (var k = 0; k < list.length; k++) {
                                            if (String(list[k][item.source.value_key]) === String(item.value[idx])) {
                                                labels.push(list[k][item.source.label_key]);
                                                break;
                                            }
                                        }
                                    }
                                    $cell.text(labels.length ? labels.join('、') : '-');
                                } else {
                                    var label = null;
                                    for (var k = 0; k < list.length; k++) {
                                        if (String(list[k][item.source.value_key]) === String(item.value)) {
                                            label = list[k][item.source.label_key];
                                            break;
                                        }
                                    }
                                    if (label !== null && label !== undefined) {
                                        $cell.text(label);
                                    }
                                }
                            }
                        }
                    });
                });
            }

            html += '</div>';

            layer.open({
                type: 1,
                title: '用户详情：' + d.username,
                area: ['520px', '640px'],
                shadeClose: true,
                content: html
            });
        }

        function buildGroupSelect(selectedId) {
            var html = '<option value="">请选择用户组</option>';
            for (var i = 0; i < groupOptions.length; i++) {
                var selected = (selectedId && groupOptions[i].id == selectedId) ? ' selected' : '';
                html += '<option value="' + groupOptions[i].id + '"' + selected + '>' + groupOptions[i].name + '</option>';
            }
            return html;
        }

        window.add = function() {
            layer.open({
                type: 2,
                title: '新增前台用户',
                shade: 0.1,
                area: ['550px', '560px'],
                content: '/admin/front-user/form'
            });
        };

        window.edit = function(obj) {
            layer.open({
                type: 2,
                title: '编辑用户：' + obj.data.username,
                shade: 0.1,
                area: ['550px', '560px'],
                content: '/admin/front-user/form?id=' + obj.data.id
            });
        };

        window.resetPassword = function(obj) {
            layer.prompt({
                formType: 1,
                title: '重置用户【' + obj.data.username + '】的密码',
                value: '',
            }, function(value, index) {
                layer.close(index);
                var loading = layer.load();
                $.ajax({
                    url: '/api/admin/front-users/' + obj.data.id + '/reset-password',
                    type: 'PUT',
                    dataType: 'json',
                    contentType: 'application/json',
                    data: JSON.stringify({ password: value }),
                    success: function(res) {
                        layer.close(loading);
                        if (res.code === 0) {
                            layer.msg('重置成功', { icon: 1, time: 1000 });
                        } else {
                            layer.msg(res.message || '重置失败', { icon: 2, time: 1000 });
                        }
                    },
                    error: function() {
                        layer.close(loading);
                        layer.msg('请求失败', { icon: 2, time: 1000 });
                    }
                });
            });
        };

        window.remove = function(obj) {
            layer.confirm('确定要删除该用户？删除后无法恢复！', {
                icon: 3,
                title: '操作提示',
                btn: ['确定', '取消']
            }, function(index) {
                layer.close(index);
                var loading = layer.load();
                $.ajax({
                    url: '/api/admin/front-users/' + obj.data.id,
                    type: 'DELETE',
                    dataType: 'json',
                    success: function(res) {
                        layer.close(loading);
                        if (res.code === 0) {
                            layer.msg('删除成功', { icon: 1, time: 1000 }, function() {
                                table.reload('user-table');
                            });
                        } else {
                            layer.msg(res.message || '删除失败', { icon: 2, time: 1000 });
                        }
                    },
                    error: function() {
                        layer.close(loading);
                        layer.msg('请求失败', { icon: 2, time: 1000 });
                    }
                });
            });
        };

        window.batchRemove = function(obj) {
            var checkData = table.checkStatus('user-table').data;
            if (checkData.length === 0) {
                layer.msg('未选中数据', { icon: 3, time: 1000 });
                return false;
            }
            var ids = checkData.map(function(item) { return item.id; });
            layer.confirm('确定要删除选中的 ' + ids.length + ' 个用户？删除后无法恢复！', {
                icon: 3,
                title: '操作提示',
                btn: ['确定', '取消']
            }, function(index) {
                layer.close(index);
                var loading = layer.load();
                $.ajax({
                    url: '/api/admin/front-users/batch-delete',
                    type: 'DELETE',
                    dataType: 'json',
                    contentType: 'application/json',
                    data: JSON.stringify({ ids: ids }),
                    success: function(res) {
                        layer.close(loading);
                        if (res.code === 0) {
                            layer.msg('删除成功', { icon: 1, time: 1000 }, function() {
                                table.reload('user-table');
                            });
                        } else {
                            layer.msg(res.message || '删除失败', { icon: 2, time: 1000 });
                        }
                    },
                    error: function() {
                        layer.close(loading);
                        layer.msg('请求失败', { icon: 2, time: 1000 });
                    }
                });
            });
        };

        // ========== 扩展字段管理 ==========
        var extFieldApi = '/api/admin/user-ext-fields';

        // 打开扩展管理弹窗
        $('#btn-ext-fields').on('click', function() {
            layer.open({
                type: 1,
                title: '扩展字段管理',
                shade: 0.1,
                area: ['900px', '560px'],
                content: '<div style="padding:10px 15px;"><table id="ext-field-table" lay-filter="ext-field-table"></table></div>',
                success: function(layero, index) {
                    renderExtFieldTable(index);
                }
            });
        });

        function renderExtFieldTable(layerIndex) {
            table.render({
                elem: '#ext-field-table',
                url: extFieldApi,
                page: false,
                cols: [[
                    { title: 'ID', field: 'id', align: 'center', sort: true },
                    { title: '字段标识', field: 'field_name', align: 'center' },
                    { title: '显示名称', field: 'field_label', align: 'center'},
                    { title: '字段类型', field: 'field_type', align: 'center'},
                    { title: '排序', field: 'sort', align: 'center', sort: true },
                    { title: '状态', field: 'status', align: 'center', templet: '#ext-field-status-tpl' },
                    { title: '操作', toolbar: '#ext-field-bar-tpl', align: 'center', width: 150, fixed: 'right' }
                ]],
                skin: false,
                toolbar: '<div class="layui-btn-container"><button class="layui-btn layui-btn-sm" lay-event="addExtField"><i class="layui-icon layui-icon-add-1"></i> 新增</button></div>',
                parseData: function(res) {
                    return {
                        "code": res.code === 0 ? 0 : 1,
                        "msg": res.message || "",
                        "data": res.data || []
                    };
                }
            });

            // 扩展字段表格工具栏事件
            table.on('toolbar(ext-field-table)', function(obj) {
                if (obj.event === 'addExtField') {
                    openExtFieldForm();
                }
            });

            // 扩展字段行操作事件
            table.on('tool(ext-field-table)', function(obj) {
                if (obj.event === 'edit') {
                    openExtFieldForm(obj.data);
                } else if (obj.event === 'del') {
                    layer.confirm('确定要删除该扩展字段？', {
                        icon: 3,
                        title: '操作提示',
                        btn: ['确定', '取消']
                    }, function(confirmIndex) {
                        layer.close(confirmIndex);
                        var loading = layer.load();
                        $.ajax({
                            url: extFieldApi + '/' + obj.data.id,
                            type: 'DELETE',
                            dataType: 'json',
                            success: function(res) {
                                layer.close(loading);
                                if (res.code === 0) {
                                    layer.msg('删除成功', { icon: 1, time: 1000 });
                                    table.reload('ext-field-table');
                                } else {
                                    layer.msg(res.message || '删除失败', { icon: 2, time: 1000 });
                                }
                            },
                            error: function() {
                                layer.close(loading);
                                layer.msg('请求失败', { icon: 2, time: 1000 });
                            }
                        });
                    });
                }
            });

            // 扩展字段状态切换
            form.on('switch(ext-field-status)', function(obj) {
                var id = this.value;
                $.ajax({
                    url: extFieldApi + '/' + id,
                    type: 'PUT',
                    dataType: 'json',
                    contentType: 'application/json',
                    data: JSON.stringify({ status: obj.elem.checked ? 1 : 0 }),
                    success: function(res) {
                        if (res.code === 0) {
                            layer.msg('状态更新成功', { icon: 1, time: 1000 });
                        } else {
                            layer.msg(res.message || '操作失败', { icon: 2, time: 1000 });
                            $(obj.elem).prop('checked', !obj.elem.checked);
                            form.render();
                        }
                    },
                    error: function() {
                        layer.msg('请求失败', { icon: 2, time: 1000 });
                        $(obj.elem).prop('checked', !obj.elem.checked);
                        form.render();
                    }
                });
            });
        }

        // 新增/编辑扩展字段表单弹窗
        function openExtFieldForm(data) {
            var isEdit = !!data;
            var title = isEdit ? '编辑扩展字段' : '新增扩展字段';
            var fieldTypeVal = isEdit ? (data.field_type || 'text') : 'text';
            var sortVal = isEdit ? (data.sort || 0) : 0;
            var statusChecked = isEdit ? (data.status == 1) : true;

            // 解析 field_options：可能是静态数组、动态数据源、或空
            var optionsJsonVal = '';
            var sourceUrlVal = '', sourceLabelKeyVal = 'name', sourceValueKeyVal = 'id';
            var optionsMode = 'static';
            if (isEdit && data.field_options) {
                var opts = data.field_options;
                if (opts && typeof opts === 'object' && opts.source) {
                    optionsMode = 'source';
                    sourceUrlVal = opts.source.url || '';
                    sourceLabelKeyVal = opts.source.label_key || 'name';
                    sourceValueKeyVal = opts.source.value_key || 'id';
                } else if (Array.isArray(opts)) {
                    optionsJsonVal = JSON.stringify(opts, null, 2);
                } else if (opts && typeof opts === 'object' && opts.options) {
                    // 多选静态选项：{ multiple: true, options: [...] }
                    optionsJsonVal = JSON.stringify(opts.options, null, 2);
                }
            }
            var optionsDisplay = (fieldTypeVal === 'select') ? 'block' : 'none';
            var multipleChecked = (isEdit && data.field_options && data.field_options.multiple === true) ? ' checked' : '';

            var formHtml = '<form class="layui-form" lay-filter="ext-field-form" style="padding:20px 30px 0;">' +
                '<div class="layui-form-item"><label class="layui-form-label">字段标识</label><div class="layui-input-block"><input type="text" name="field_name" lay-verify="required" placeholder="英文字母下划线，如 company" class="layui-input" value="' + (isEdit ? (data.field_name || '') : '') + '"></div></div>' +
                '<div class="layui-form-item"><label class="layui-form-label">显示名称</label><div class="layui-input-block"><input type="text" name="field_label" lay-verify="required" placeholder="如：公司名称" class="layui-input" value="' + (isEdit ? (data.field_label || '') : '') + '"></div></div>' +
                '<div class="layui-form-item"><label class="layui-form-label">字段类型</label><div class="layui-input-block"><select name="field_type" lay-filter="ext-field-type">' +
                '<option value="text"' + (fieldTypeVal === 'text' ? ' selected' : '') + '>文本(text)</option>' +
                '<option value="number"' + (fieldTypeVal === 'number' ? ' selected' : '') + '>数字(number)</option>' +
                '<option value="select"' + (fieldTypeVal === 'select' ? ' selected' : '') + '>下拉选择(select)</option>' +
                '<option value="textarea"' + (fieldTypeVal === 'textarea' ? ' selected' : '') + '>多行文本(textarea)</option>' +
                '<option value="switch"' + (fieldTypeVal === 'switch' ? ' selected' : '') + '>开关(switch)</option>' +
                '<option value="date"' + (fieldTypeVal === 'date' ? ' selected' : '') + '>日期(date)</option>' +
                '<option value="json"' + (fieldTypeVal === 'json' ? ' selected' : '') + '>JSON(json)</option>' +
                '</select></div></div>' +
                '<div class="layui-form-item" id="ext-options-wrap" style="display:' + optionsDisplay + ';"><label class="layui-form-label">选项来源</label><div class="layui-input-block"><select name="options_mode" lay-filter="ext-options-mode">' +
                '<option value="static"' + (optionsMode === 'static' ? ' selected' : '') + '>静态选项</option>' +
                '<option value="source"' + (optionsMode === 'source' ? ' selected' : '') + '>动态数据源</option>' +
                '</select></div></div>' +
                '<div class="layui-form-item" id="ext-multiple-wrap" style="display:' + optionsDisplay + ';"><label class="layui-form-label">多选</label><div class="layui-input-block"><input type="checkbox" name="ext_multiple" lay-skin="switch" lay-text="是|否"' + multipleChecked + '></div></div>' +
                '<div class="layui-form-item" id="ext-options-json-wrap" style="display:' + (optionsDisplay === 'block' && optionsMode === 'static' ? 'block' : 'none') + ';"><label class="layui-form-label">选项JSON</label><div class="layui-input-block"><textarea name="options_json" placeholder=\'[{"label":"选项1","value":"1"},{"label":"选项2","value":"2"}]\' class="layui-textarea">' + optionsJsonVal + '</textarea></div></div>' +
                '<div class="layui-form-item" id="ext-options-source-wrap" style="display:' + (optionsDisplay === 'block' && optionsMode === 'source' ? 'block' : 'none') + ';"><label class="layui-form-label">数据源URL</label><div class="layui-input-block"><input type="text" name="source_url" value="' + sourceUrlVal + '" placeholder="如：/api/admin/cmspro/childrehab/hospitals" class="layui-input"></div><div style="margin-top:10px;padding-left:110px;color:#999;font-size:12px;">URL 需返回 {code:0, data:[...]} 格式的 JSON，data 为数组</div></div>' +
                '<div class="layui-form-item" id="ext-options-keys-wrap" style="display:' + (optionsDisplay === 'block' && optionsMode === 'source' ? 'block' : 'none') + ';"><label class="layui-form-label">字段映射</label><div class="layui-input-block layui-row layui-col-space10"><div class="layui-col-md6"><input type="text" name="source_label_key" value="' + sourceLabelKeyVal + '" placeholder="显示字段，如 name" class="layui-input"></div><div class="layui-col-md6"><input type="text" name="source_value_key" value="' + sourceValueKeyVal + '" placeholder="值字段，如 id" class="layui-input"></div></div></div>' +
                '<div class="layui-form-item"><label class="layui-form-label">排序</label><div class="layui-input-block"><input type="number" name="sort" value="' + sortVal + '" class="layui-input"></div></div>' +
                '<div class="layui-form-item"><label class="layui-form-label">状态</label><div class="layui-input-block"><input type="checkbox" name="status" lay-skin="switch" lay-text="启用|禁用" ' + (statusChecked ? 'checked' : '') + '></div></div>' +
                '<div class="layui-form-item" style="text-align:center;padding-top:10px;"><button type="button" class="layui-btn" lay-submit lay-filter="ext-field-submit">提交</button><button type="reset" class="layui-btn layui-btn-primary">重置</button></div>' +
                '</form>';

            layer.open({
                type: 1,
                title: title,
                shade: 0.1,
                area: ['500px', '560px'],
                content: formHtml,
                success: function() {
                    form.render();

                    // 字段类型切换
                    form.on('select(ext-field-type)', function(obj) {
                        var $wrap = $('#ext-options-wrap');
                        var $json = $('#ext-options-json-wrap');
                        var $src = $('#ext-options-source-wrap');
                        var $keys = $('#ext-options-keys-wrap');
                        var $multiple = $('#ext-multiple-wrap');
                        if (obj.value === 'select') {
                            $wrap.show();
                            $multiple.show();
                            var mode = $('select[name="options_mode"]').val();
                            if (mode === 'source') { $src.show(); $keys.show(); $json.hide(); }
                            else { $json.show(); $src.hide(); $keys.hide(); }
                        } else {
                            $wrap.hide(); $json.hide(); $src.hide(); $keys.hide();
                            $multiple.hide();
                        }
                    });

                    // 选项来源切换
                    form.on('select(ext-options-mode)', function(obj) {
                        var $json = $('#ext-options-json-wrap');
                        var $src = $('#ext-options-source-wrap');
                        var $keys = $('#ext-options-keys-wrap');
                        if (obj.value === 'source') { $src.show(); $keys.show(); $json.hide(); }
                        else { $json.show(); $src.hide(); $keys.hide(); }
                    });

                    form.on('submit(ext-field-submit)', function(formData) {
                        var submitData = formData.field;
                        // switch 未选中时不提交，手动处理
                        submitData.status = submitData.status ? 1 : 0;

                        // 组装 field_options
                        var fieldOptions = null;
                        if (submitData.field_type === 'select') {
                            var mode = submitData.options_mode;
                            if (mode === 'source') {
                                if (!submitData.source_url) {
                                    layer.msg('请填写数据源URL', { icon: 2, time: 1500 });
                                    return false;
                                }
                                fieldOptions = {
                                    source: {
                                        url: submitData.source_url,
                                        label_key: submitData.source_label_key || 'name',
                                        value_key: submitData.source_value_key || 'id'
                                    }
                                };
                            } else if (submitData.options_json) {
                                try {
                                    var parsed = JSON.parse(submitData.options_json);
                                    if (!Array.isArray(parsed)) {
                                        layer.msg('选项JSON 必须是数组', { icon: 2, time: 1500 });
                                        return false;
                                    }
                                    fieldOptions = parsed;
                                } catch(e) {
                                    layer.msg('选项JSON 格式错误：' + e.message, { icon: 2, time: 1500 });
                                    return false;
                                }
                            }
                            // 多选标记
                            var isMultiple = $('input[name="ext_multiple"]').is(':checked');
                            if (isMultiple) {
                                if (fieldOptions === null) {
                                    fieldOptions = {};
                                } else if (Array.isArray(fieldOptions)) {
                                    fieldOptions = { options: fieldOptions };
                                }
                                fieldOptions.multiple = true;
                            }
                        }
                        delete submitData.options_mode;
                        delete submitData.options_json;
                        delete submitData.source_url;
                        delete submitData.source_label_key;
                        delete submitData.source_value_key;
                        submitData.field_options = fieldOptions;

                        var loading = layer.load();
                        var ajaxOpts = {
                            dataType: 'json',
                            contentType: 'application/json',
                            data: JSON.stringify(submitData),
                            success: function(res) {
                                layer.close(loading);
                                if (res.code === 0) {
                                    layer.msg(isEdit ? '更新成功' : '创建成功', { icon: 1, time: 1000 }, function() {
                                        layer.closeAll();
                                        table.reload('ext-field-table');
                                    });
                                } else {
                                    layer.msg(res.message || '操作失败', { icon: 2, time: 1000 });
                                }
                            },
                            error: function() {
                                layer.close(loading);
                                layer.msg('请求失败', { icon: 2, time: 1000 });
                            }
                        };

                        if (isEdit) {
                            ajaxOpts.url = extFieldApi + '/' + data.id;
                            ajaxOpts.type = 'PUT';
                        } else {
                            ajaxOpts.url = extFieldApi;
                            ajaxOpts.type = 'POST';
                        }
                        $.ajax(ajaxOpts);
                        return false;
                    });
                }
            });
        }
    });
</script>
</body>
</html>