<!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>
    .attachment-wrap { display: flex; gap: 12px; height: calc(100vh - 60px); }
    .group-panel { width: 220px; min-width: 220px; background: #fff; border-radius: 6px; display: flex; flex-direction: column; }
    .group-panel .panel-header { padding: 12px 15px; border-bottom: 1px solid #f0f0f0; font-weight: 600; font-size: 14px; display: flex; justify-content: space-between; align-items: center; }
    .group-panel .panel-header .add-btn { cursor: pointer; color: #16b777; font-size: 18px; }
    .group-panel .panel-body { flex: 1; overflow-y: auto; padding: 8px 0; }
    .group-item { padding: 9px 15px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; font-size: 13px; color: #333; transition: background .2s; }
    .group-item:hover { background: #f6f6f6; }
    .group-item.active { background: #e8f5e9; color: #16b777; font-weight: 500; }
    .group-item .group-name { display: flex; align-items: center; gap: 6px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .group-item .group-name i { font-size: 14px; color: #999; }
    .group-item .group-count { color: #999; font-size: 12px; margin-right: 4px; }
    .group-item .group-ops { display: none; gap: 4px; }
    .group-item:hover .group-ops { display: flex; }
    .group-item:hover .group-count { display: none; }
    .group-item .group-ops i { font-size: 13px; color: #999; padding: 2px; }
    .group-item .group-ops i:hover { color: #16b777; }
    .content-panel { flex: 1; display: flex; flex-direction: column; gap: 12px; min-width: 0; }
    .upload-zone { border: 2px dashed #ddd; border-radius: 8px; padding: 30px; text-align: center; cursor: pointer; transition: border-color .2s, background .2s; }
    .upload-zone:hover, .upload-zone.dragover { border-color: #16b777; background: #f0faf2; }
    .upload-zone i { font-size: 48px; color: #16b777; display: block; margin-bottom: 10px; }
    .upload-zone p { color: #999; font-size: 13px; }
    .upload-zone .upload-hint { font-size: 12px; color: #bbb; margin-top: 6px; }
    .upload-file-list { margin-top: 12px; max-height: 200px; overflow-y: auto; }
    .upload-file-item { display: flex; align-items: center; justify-content: space-between; padding: 6px 10px; background: #f9f9f9; border-radius: 4px; margin-bottom: 4px; font-size: 13px; }
    .upload-file-item .file-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .upload-file-item .file-size { color: #999; margin-left: 10px; }
    .upload-file-item .file-remove { color: #ff5722; cursor: pointer; margin-left: 10px; }
    .att-preview { width: 36px; height: 36px; object-fit: cover; border-radius: 4px; border: 1px solid #eee; }
    .att-file-icon { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: 4px; background: #f5f5f5; color: #999; font-size: 20px; }
    .att-name { display: flex; align-items: center; gap: 8px; }
    .att-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 200px; }
    .category-tag { display: inline-block; padding: 1px 6px; border-radius: 3px; font-size: 12px; }
    .category-tag.image { background: #e8f5e9; color: #4caf50; }
    .category-tag.file { background: #e3f2fd; color: #2196f3; }
    .category-tag.video { background: #fff3e0; color: #ff9800; }
    .upload-config-bar { background: #fff; border-radius: 6px; padding: 12px 16px; margin-bottom: 12px; display: flex; flex-wrap: wrap; gap: 16px; align-items: center; font-size: 13px; }
    .upload-config-bar .cfg-title { font-weight: 600; color: #333; margin-right: 4px; }
    .upload-config-bar .cfg-item { display: flex; align-items: center; gap: 4px; color: #666; }
    .upload-config-bar .cfg-item .cfg-label { color: #999; }
    .upload-config-bar .cfg-item .cfg-value { color: #16b777; font-weight: 500; }
    .upload-config-bar .cfg-item .cfg-exts { color: #888; font-size: 12px; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .upload-config-bar .cfg-divider { width: 1px; height: 24px; background: #eee; }
    .upload-config-bar .hash-status { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 10px; font-size: 12px; }
    .upload-config-bar .hash-status.on { background: #e8f5e9; color: #4caf50; }
    .upload-config-bar .hash-status.off { background: #f5f5f5; color: #999; }
</style>
    @include('admin.partials.permission-script')
</head>
<body>
<div class="pear-container" style="padding: 12px;">
    <div class="attachment-wrap">
        <div class="group-panel">
            <div class="panel-header">
                <span>分组列表</span>
                <i class="layui-icon layui-icon-add-1 add-btn" id="addGroupBtn" title="新增分组"></i>
            </div>
            <div class="panel-body" id="groupList"></div>
        </div>

        <div class="content-panel">
            <div class="layui-card">
                <div class="layui-card-body">
                    <form class="layui-form" action="" id="searchForm">
                        <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="category">
                                    <option value="">全部类型</option>
                                    <option value="image">图片</option>
                                    <option value="file">文件</option>
                                    <option value="video">视频</option>
                                </select>
                            </div>
                        </div>
                        <div class="layui-inline">
                            <div class="layui-input-inline" style="width:120px;">
                                <input type="text" name="start_date" id="startDate" placeholder="开始日期" class="layui-input">
                            </div>
                        </div>
                        <div class="layui-inline">
                            <div class="layui-input-inline" style="width:120px;">
                                <input type="text" name="end_date" id="endDate" placeholder="结束日期" class="layui-input">
                            </div>
                        </div>
                        <div class="layui-inline">
                            <button class="layui-btn layui-btn-md" lay-submit lay-filter="att-query">
                                <i class="layui-icon layui-icon-search"></i> 查询
                            </button>
                            <button type="reset" class="layui-btn layui-btn-md layui-btn-primary" id="resetBtn">
                                <i class="layui-icon layui-icon-refresh"></i> 重置
                            </button>
                        </div>
                    </form>
                </div>
            </div>

            <div class="upload-config-bar" id="uploadConfigBar">
                <span class="cfg-title">上传配置</span>
                <div class="cfg-item"><span class="cfg-label">图片：</span><span class="cfg-value" id="cfgImgSize">-</span><span class="cfg-exts" id="cfgImgExts"></span></div>
                <div class="cfg-divider"></div>
                <div class="cfg-item"><span class="cfg-label">文件：</span><span class="cfg-value" id="cfgFileSize">-</span><span class="cfg-exts" id="cfgFileExts"></span></div>
                <div class="cfg-divider"></div>
                <div class="cfg-item"><span class="cfg-label">视频：</span><span class="cfg-value" id="cfgVideoSize">-</span><span class="cfg-exts" id="cfgVideoExts"></span></div>
                <div class="cfg-divider"></div>
                <div class="cfg-item"><span class="cfg-label">去重：</span><span class="hash-status on" id="cfgHashStatus"><i class="fa fa-check-circle"></i> 开启</span></div>
            </div>

            <div class="layui-card" style="flex:1; display:flex; flex-direction:column;">
                <div class="layui-card-body" style="flex:1; display:flex; flex-direction:column;">
                    <table id="att-table" lay-filter="att-table"></table>
                </div>
            </div>
        </div>
    </div>

    <script type="text/html" id="att-toolbar">
        <button class="layui-btn layui-btn-sm" lay-event="upload" data-permission="admin.attachment.upload">
            <i class="layui-icon layui-icon-upload"></i> 上传附件
        </button>
        <button class="layui-btn layui-btn-sm layui-btn-warm" lay-event="moveGroup">
            <i class="fa fa-folder-open"></i> 移动分组
        </button>
        <button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="batchRemove" data-permission="admin.attachment.batch-delete">
            <i class="layui-icon layui-icon-delete"></i> 批量删除
        </button>
    </script>

    @verbatim
    <script type="text/html" id="att-name-tpl">
        <div class="att-name">
            {{# if(d.category === 'image' && d.url) { }}
            <img src="{{ d.url }}" class="att-preview" onerror="this.style.display='none';this.nextElementSibling.style.display='flex';">
            <div class="att-file-icon" style="display:none;"><i class="layui-icon layui-icon-picture"></i></div>
            {{# } else if(d.category === 'video') { }}
            <div class="att-file-icon"><i class="layui-icon layui-icon-video"></i></div>
            {{# } else { }}
            <div class="att-file-icon"><i class="layui-icon layui-icon-file"></i></div>
            {{# } }}
            <span title="{{ d.name }}">{{ d.name }}</span>
        </div>
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="att-category-tpl">
        <span class="category-tag {{ d.category }}">{{# if(d.category === 'image'){ }}图片{{# } else if(d.category === 'video'){ }}视频{{# } else { }}文件{{# } }}</span>
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="att-size-tpl">
        {{# if(d.size < 1024){ }}{{ d.size }}B{{# } else if(d.size < 1024*1024){ }}{{ (d.size/1024).toFixed(1) }}KB{{# } else { }}{{ (d.size/1024/1024).toFixed(1) }}MB{{# } }}
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="att-group-tpl">
        {{# if(d.attachment_group){ }}{{ d.attachment_group.name }}{{# } else { }}<span style="color:#999">未分组</span>{{# } }}
    </script>
    @endverbatim

    @verbatim
    <script type="text/html" id="att-bar">
        <div class="layui-btn-container">
            <a class="layui-btn layui-btn-xs layui-btn-normal picker-select-btn" lay-event="select" style="display:none;">选择</a>
            <a class="layui-btn layui-btn-xs" lay-event="preview">预览</a>
            <a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="download">下载</a>
            <a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="copyUrl">复制</a>
            <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del" data-permission="admin.attachment.destroy">删除</a>
        </div>
    </script>
    @endverbatim
</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', 'laydate', 'layer'], function() {
        var table = layui.table;
        var form = layui.form;
        var $ = layui.jquery;
        var laydate = layui.laydate;
        var layer = layui.layer;

        $.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);
                    });
                }
            }
        });

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

        var currentGroupId = '';
        var isPickerMode = location.search.indexOf('picker=1') !== -1;

        if (isPickerMode) {
            $('.picker-select-btn').show();
        }

        laydate.render({ elem: '#startDate' });
        laydate.render({ elem: '#endDate' });

        loadGroups();

        function loadGroups() {
            $.get('/api/admin/attachment-groups', function(res) {
                if (res.code !== 0) return;
                var html = '<div class="group-item' + (currentGroupId === '' ? ' active' : '') + '" data-id="">'
                    + '<div class="group-name"><i class="fa fa-files-o"></i> 全部附件</div></div>';
                html += '<div class="group-item' + (currentGroupId === '0' ? ' active' : '') + '" data-id="0">'
                    + '<div class="group-name"><i class="fa fa-star-o"></i> 未分组</div></div>';
                var groups = res.data || [];
                for (var i = 0; i < groups.length; i++) {
                    var g = groups[i];
                    html += '<div class="group-item' + (currentGroupId == g.id ? ' active' : '') + '" data-id="' + g.id + '">'
                        + '<div class="group-name"><i class="fa fa-folder-o"></i> ' + g.name + '</div>'
                        + '<span class="group-count">' + (g.attachments_count || 0) + '</span>'
                        + '<div class="group-ops">'
                        + '<i class="fa fa-edit" data-action="edit" data-id="' + g.id + '" data-name="' + g.name + '" data-desc="' + (g.description || '') + '" title="编辑"></i>'
                        + '<i class="fa fa-trash-o" data-action="del" data-id="' + g.id + '" data-name="' + g.name + '" title="删除"></i>'
                        + '</div></div>';
                }
                $('#groupList').html(html);
                bindGroupEvents();
            });
        }

        function bindGroupEvents() {
            $('.group-item').on('click', function(e) {
                if ($(e.target).closest('.group-ops').length) return;
                currentGroupId = $(this).data('id') + '';
                $('.group-item').removeClass('active');
                $(this).addClass('active');
                table.reload('att-table', { where: { group_id: currentGroupId }, page: { curr: 1 } });
            });

            $('.group-ops i').on('click', function(e) {
                e.stopPropagation();
                var action = $(this).data('action');
                var id = $(this).data('id');
                if (action === 'edit') {
                    openGroupForm(id, $(this).data('name'), $(this).data('desc'));
                } else if (action === 'del') {
                    deleteGroup(id, $(this).data('name'));
                }
            });
        }

        $('#addGroupBtn').on('click', function() { openGroupForm(null, '', ''); });

        function openGroupForm(id, name, desc) {
            var isEdit = !!id;
            layer.open({
                type: 1,
                title: isEdit ? '编辑分组' : '新增分组',
                area: ['380px', '240px'],
                content: '<form class="layui-form" style="padding:20px;" lay-filter="groupForm">'
                    + '<div class="layui-form-item"><label class="layui-form-label">名称</label>'
                    + '<div class="layui-input-block"><input type="text" name="name" value="' + (name || '') + '" class="layui-input" placeholder="分组名称" lay-verify="required"></div></div>'
                    + '<div class="layui-form-item"><label class="layui-form-label">描述</label>'
                    + '<div class="layui-input-block"><input type="text" name="description" value="' + (desc || '') + '" class="layui-input" placeholder="分组描述（可选）"></div></div>'
                    + '<div class="layui-form-item" style="text-align:right;margin-top:16px;">'
                    + '<button type="button" class="layui-btn layui-btn-primary" id="groupCancelBtn">取消</button> '
                    + '<button type="button" class="layui-btn" id="groupSubmitBtn">确定</button></div></form>',
                success: function(layero) {
                    form.render(null, 'groupForm');
                    layero.find('#groupCancelBtn').on('click', function() { layer.closeAll(); });
                    layero.find('#groupSubmitBtn').on('click', function() {
                        var gName = layero.find('input[name=name]').val().trim();
                        var gDesc = layero.find('input[name=description]').val().trim();
                        if (!gName) { layer.msg('请输入分组名称', { icon: 5 }); return; }
                        var url = isEdit ? '/api/admin/attachment-groups/' + id : '/api/admin/attachment-groups';
                        var method = isEdit ? 'PUT' : 'POST';
                        $.ajax({
                            url: url, type: method, dataType: 'json',
                            contentType: 'application/json',
                            data: JSON.stringify({ name: gName, description: gDesc }),
                            success: function(res) {
                                if (res.code === 0) {
                                    layer.msg(isEdit ? '更新成功' : '创建成功', { icon: 1, time: 1000 });
                                    layer.closeAll();
                                    loadGroups();
                                } else {
                                    layer.msg(res.message || '操作失败', { icon: 2 });
                                }
                            },
                            error: function() { layer.msg('请求失败', { icon: 2 }); }
                        });
                    });
                }
            });
        }

        function deleteGroup(id, name) {
            layer.confirm('确定删除分组"' + name + '"？分组下的附件将移至"未分组"', { icon: 3, title: '操作提示' }, function(index) {
                layer.close(index);
                $.ajax({
                    url: '/api/admin/attachment-groups/' + id, type: 'DELETE', dataType: 'json',
                    success: function(res) {
                        if (res.code === 0) {
                            layer.msg('删除成功', { icon: 1, time: 1000 });
                            if (currentGroupId == id) { currentGroupId = ''; }
                            loadGroups();
                            table.reload('att-table');
                        } else {
                            layer.msg(res.message || '删除失败', { icon: 2 });
                        }
                    },
                    error: function() { layer.msg('请求失败', { icon: 2 }); }
                });
            });
        }

        var cols = [[
            { type: 'checkbox', fixed: 'left' },
            { title: 'ID', field: 'id', align: 'center', width: 70, sort: true },
            { title: '文件', field: 'name', align: 'center', minWidth: 200, templet: '#att-name-tpl' },
            { title: '大小', field: 'size', align: 'center', width: 100, templet: '#att-size-tpl' },
            { title: '类型', field: 'category', align: 'center', width: 80, templet: '#att-category-tpl' },
            { title: '分组', field: 'attachment_group', align: 'center', width: 100, templet: '#att-group-tpl' },
            { title: '上传人', field: 'user', align: 'center', width: 90, templet: function(d) {
                return d.user ? d.user.name : '-';
            }},
            { title: '上传时间', field: 'create_time', align: 'center', width: 170 },
            { title: '操作', toolbar: '#att-bar', align: 'center', width: 250, fixed: 'right' }
        ]];

        table.render({
            elem: '#att-table',
            url: '/api/admin/attachments',
            page: { layout: ['count', 'prev', 'page', 'next', 'limit'], groups: 5, limit: 20, limits: [10, 20, 50, 100] },
            cols: cols,
            skin: false,
            toolbar: '#att-toolbar',
            defaultToolbar: [{ title: '刷新', layEvent: 'refresh', icon: 'layui-icon-refresh' }, 'filter', 'print', 'exports'],
            where: { group_id: currentGroupId },
            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 : []
                };
            },
            done: function() {
                if (isPickerMode) {
                    $('.picker-select-btn').show();
                }
                // 根据权限隐藏行内操作按钮
                $('td [data-permission]').each(function() {
                    if (!window.hasPermission || !window.hasPermission($(this).data('permission'))) {
                        $(this).hide();
                    }
                });
            }
        });

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

        $('#resetBtn').on('click', function() {
            currentGroupId = '';
            $('.group-item').removeClass('active');
            $('.group-item').first().addClass('active');
            setTimeout(function() { table.reload('att-table', { where: {}, page: { curr: 1 } }); }, 50);
        });

        table.on('toolbar(att-table)', function(obj) {
            if (obj.event === 'upload') { openUploadDialog(); }
            else if (obj.event === 'moveGroup') { openMoveGroupDialog(); }
            else if (obj.event === 'batchRemove') { batchRemove(); }
            else if (obj.event === 'refresh') { table.reload('att-table'); }
        });

        table.on('tool(att-table)', function(obj) {
            var d = obj.data;
            if (obj.event === 'select') { selectFile(d); }
            else if (obj.event === 'preview') { previewFile(d); }
            else if (obj.event === 'download') { downloadFile(d); }
            else if (obj.event === 'copyUrl') { copyUrl(d); }
            else if (obj.event === 'del') { removeFile(obj); }
        });

        var uploadConfig = null;

        function loadUploadConfig(callback) {
            if (uploadConfig) { callback(uploadConfig); return; }
            $.get('/api/admin/attachments/upload-config', function(res) {
                if (res.code === 0) {
                    uploadConfig = res.data;
                    renderUploadConfigBar(res.data);
                }
                callback(uploadConfig || {});
            }).fail(function() { callback({}); });
        }

        function renderUploadConfigBar(cfg) {
            $('#cfgImgSize').text((cfg.image_max_size_mb || 0) + 'MB');
            $('#cfgImgExts').text((cfg.image_extensions || []).join(','));
            $('#cfgFileSize').text((cfg.file_max_size_mb || 0) + 'MB');
            $('#cfgFileExts').text((cfg.file_extensions || []).join(','));
            $('#cfgVideoSize').text((cfg.video_max_size_mb || 0) + 'MB');
            $('#cfgVideoExts').text((cfg.video_extensions || []).join(','));
            var $hash = $('#cfgHashStatus');
            if (cfg.hash_check) {
                $hash.removeClass('off').addClass('on').html('<i class="fa fa-check-circle"></i> 开启');
            } else {
                $hash.removeClass('on').addClass('off').html('<i class="fa fa-times-circle"></i> 关闭');
            }
        }

        loadUploadConfig(function() {});

        function openUploadDialog() {
            loadUploadConfig(function(cfg) {
                var imgMax = cfg.image_max_size_mb || 5;
                var fileMax = cfg.file_max_size_mb || 20;
                var videoMax = cfg.video_max_size_mb || 100;
                var imgExts = (cfg.image_extensions || []).join(', ');
                var fileExts = (cfg.file_extensions || []).join(', ');
                var videoExts = (cfg.video_extensions || []).join(', ');
                var hintParts = [];
                if (imgExts) hintParts.push('图片最大' + imgMax + 'MB（' + imgExts + '）');
                if (fileExts) hintParts.push('文件最大' + fileMax + 'MB（' + fileExts + '）');
                if (videoExts) hintParts.push('视频最大' + videoMax + 'MB（' + videoExts + '）');
                var hintText = hintParts.length > 0 ? hintParts.join('；') : '支持图片、文档、压缩包等';

                var uploadFiles = [];
                var content = '<div style="padding:20px;">'
                    + '<div class="upload-zone" id="uploadZone" style="position:relative;">'
                    + '<input type="file" id="fileInput" multiple style="position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer;z-index:1;">'
                    + '<div style="pointer-events:none;position:relative;z-index:0;">'
                    + '<i class="layui-icon layui-icon-upload"></i>'
                    + '<p>将文件拖拽到此处，或点击选择文件</p>'
                    + '<p class="upload-hint">' + hintText + '</p>'
                    + '</div></div>'
                    + '<div class="upload-file-list" id="uploadFileList"></div>'
                    + '<div style="text-align:right;margin-top:16px;">'
                    + '<button type="button" class="layui-btn layui-btn-primary" id="uploadCancelBtn">取消</button> '
                    + '<button type="button" class="layui-btn" id="uploadSubmitBtn" disabled>开始上传</button></div></div>';

                layer.open({
                    type: 1, title: '上传附件', area: ['520px', '400px'],
                    content: content,
                    success: function(layero) {
                        var $zone = layero.find('#uploadZone');
                        var $input = layero.find('#fileInput');
                        var $list = layero.find('#uploadFileList');
                        var $submit = layero.find('#uploadSubmitBtn');

                        var allExts = [].concat(cfg.image_extensions || [], cfg.file_extensions || [], cfg.video_extensions || []);

                        $input.on('change', function() { addFiles(this.files); this.value = ''; });

                        $zone.on('dragover', function(e) { e.preventDefault(); $zone.addClass('dragover'); });
                        $zone.on('dragleave drop', function(e) { e.preventDefault(); $zone.removeClass('dragover'); });
                        $zone.on('drop', function(e) {
                            e.preventDefault();
                            var files = e.originalEvent.dataTransfer.files;
                            addFiles(files);
                        });

                        function addFiles(fileList) {
                            for (var i = 0; i < fileList.length; i++) {
                                var f = fileList[i];
                                var ext = f.name.split('.').pop().toLowerCase();
                                if (allExts.length > 0 && allExts.indexOf(ext) === -1) {
                                    layer.msg('不支持的文件类型：' + ext, { icon: 5 });
                                    continue;
                                }
                                var maxSizeKB = getMaxSizeForExt(ext, cfg);
                                if (maxSizeKB > 0 && f.size > maxSizeKB * 1024) {
                                    var maxMB = (maxSizeKB / 1024).toFixed(1);
                                    layer.msg(f.name + ' 超过大小限制（最大' + maxMB + 'MB）', { icon: 5 });
                                    continue;
                                }
                                uploadFiles.push(f);
                            }
                            renderFileList();
                        }

                        function getMaxSizeForExt(ext, c) {
                            if ((c.image_extensions || []).indexOf(ext) !== -1) return c.image_max_size || 0;
                            if ((c.video_extensions || []).indexOf(ext) !== -1) return c.video_max_size || 0;
                            if ((c.file_extensions || []).indexOf(ext) !== -1) return c.file_max_size || 0;
                            return 0;
                        }

                        function renderFileList() {
                            var html = '';
                            for (var i = 0; i < uploadFiles.length; i++) {
                                var f = uploadFiles[i];
                                var sizeStr = f.size < 1024 ? f.size + 'B' : f.size < 1048576 ? (f.size / 1024).toFixed(1) + 'KB' : (f.size / 1048576).toFixed(1) + 'MB';
                                html += '<div class="upload-file-item"><span class="file-name">' + f.name + '</span>'
                                    + '<span class="file-size">' + sizeStr + '</span>'
                                    + '<i class="fa fa-times file-remove" data-idx="' + i + '"></i></div>';
                            }
                            $list.html(html);
                            $submit.prop('disabled', uploadFiles.length === 0);

                            $list.find('.file-remove').on('click', function() {
                                uploadFiles.splice($(this).data('idx'), 1);
                                renderFileList();
                            });
                        }

                        layero.find('#uploadCancelBtn').on('click', function() { layer.closeAll(); });

                        $submit.on('click', function() {
                            if (uploadFiles.length === 0) return;
                            $submit.prop('disabled', true).text('上传中...');
                            var formData = new FormData();
                            formData.append('_token', '{{ csrf_token() }}');
                            for (var i = 0; i < uploadFiles.length; i++) {
                                formData.append('files[]', uploadFiles[i]);
                            }
                            if (currentGroupId && currentGroupId !== '') {
                                formData.append('group_id', currentGroupId);
                            }
                            $.ajax({
                                url: '/api/admin/attachments/upload',
                                type: 'POST', data: formData,
                                processData: false, contentType: false,
                                success: function(res) {
                                    if (res.code === 0) {
                                        var msg = '上传完成';
                                        if (res.data.failed_count > 0) {
                                            msg += '，' + res.data.failed_count + '个文件失败';
                                        }
                                        layer.msg(msg, { icon: res.data.failed_count > 0 ? 5 : 1, time: 1500 });
                                        layer.closeAll();
                                        table.reload('att-table');
                                        loadGroups();
                                    } else {
                                        layer.msg(res.message || '上传失败', { icon: 2 });
                                        $submit.prop('disabled', false).text('开始上传');
                                    }
                                },
                                error: function() {
                                    layer.msg('上传请求失败', { icon: 2 });
                                    $submit.prop('disabled', false).text('开始上传');
                                }
                            });
                        });
                    }
                });
            });
        }

        function selectFile(d) {
            sessionStorage.setItem('selectedAttachmentUrl', d.url);
            var parentIndex = parent.layer.getFrameIndex(window.name);
            parent.layer.close(parentIndex);
        }

        function previewFile(d) {
            if (d.category === 'image') {
                layer.open({
                    type: 1, title: d.name, area: ['auto', 'auto'],
                    maxWidth: 900, maxHeight: 600,
                    content: '<div style="padding:10px;text-align:center;"><img src="' + d.url + '" style="max-width:860px;max-height:560px;"></div>'
                });
            } else if (d.category === 'video') {
                layer.open({
                    type: 1, title: d.name, area: ['680px', '440px'],
                    content: '<div style="padding:10px;text-align:center;"><video src="' + d.url + '" controls style="max-width:640px;max-height:400px;"></video></div>'
                });
            } else {
                window.open(d.url, '_blank');
            }
        }

        function downloadFile(d) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', d.url, true);
            xhr.responseType = 'blob';
            xhr.onload = function() {
                if (xhr.status === 401) {
                    layer.msg('登录已过期，请重新登录', {icon: 2, time: 1500}, function() {
                        window.location.href = '/admin/login?redirect=' + encodeURIComponent(window.location.pathname + window.location.search);
                    });
                    return;
                }
                if (xhr.status === 200) {
                    var blob = xhr.response;
                    var link = document.createElement('a');
                    link.href = window.URL.createObjectURL(blob);
                    link.download = d.name;
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    window.URL.revokeObjectURL(link.href);
                    layer.msg('下载成功', { icon: 1, time: 1000 });
                } else {
                    layer.msg('下载失败', { icon: 2 });
                }
            };
            xhr.onerror = function() { layer.msg('下载失败', { icon: 2 }); };
            xhr.send();
        }

        function copyUrl(d) {
            var url = d.url;
            if (navigator.clipboard) {
                navigator.clipboard.writeText(url).then(function() {
                    layer.msg('已复制链接', { icon: 1, time: 1000 });
                });
            } else {
                var input = document.createElement('input');
                input.value = url;
                document.body.appendChild(input);
                input.select();
                document.execCommand('copy');
                document.body.removeChild(input);
                layer.msg('已复制链接', { icon: 1, time: 1000 });
            }
        }

        function removeFile(obj) {
            layer.confirm('确定删除该附件？删除后无法恢复！', { icon: 3, title: '操作提示' }, function(index) {
                layer.close(index);
                $.ajax({
                    url: '/api/admin/attachments/destroy', type: 'DELETE', dataType: 'json',
                    contentType: 'application/json', data: JSON.stringify({ ids: [obj.data.id] }),
                    success: function(res) {
                        if (res.code === 0) {
                            layer.msg('删除成功', { icon: 1, time: 1000 }, function() {
                                table.reload('att-table');
                                loadGroups();
                            });
                        } else {
                            layer.msg(res.message || '删除失败', { icon: 2 });
                        }
                    },
                    error: function() { layer.msg('请求失败', { icon: 2 }); }
                });
            });
        }

        function batchRemove() {
            var checkData = table.checkStatus('att-table').data;
            if (checkData.length === 0) { layer.msg('未选中数据', { icon: 3 }); return; }
            var ids = checkData.map(function(item) { return item.id; });
            layer.confirm('确定删除选中的 ' + ids.length + ' 个附件？', { icon: 3, title: '操作提示' }, function(index) {
                layer.close(index);
                $.ajax({
                    url: '/api/admin/attachments/destroy', type: 'DELETE', dataType: 'json',
                    contentType: 'application/json', data: JSON.stringify({ ids: ids }),
                    success: function(res) {
                        if (res.code === 0) {
                            layer.msg('删除成功', { icon: 1, time: 1000 }, function() {
                                table.reload('att-table');
                                loadGroups();
                            });
                        } else {
                            layer.msg(res.message || '删除失败', { icon: 2 });
                        }
                    },
                    error: function() { layer.msg('请求失败', { icon: 2 }); }
                });
            });
        }

        function openMoveGroupDialog() {
            var checkData = table.checkStatus('att-table').data;
            if (checkData.length === 0) { layer.msg('未选中数据', { icon: 3 }); return; }
            var ids = checkData.map(function(item) { return item.id; });

            $.get('/api/admin/attachment-groups', function(res) {
                if (res.code !== 0) return;
                var groups = res.data || [];
                var options = '<option value="">移至未分组</option>';
                for (var i = 0; i < groups.length; i++) {
                    options += '<option value="' + groups[i].id + '">' + groups[i].name + '</option>';
                }
                layer.open({
                    type: 1, title: '移动到分组（已选' + ids.length + '个）', area: ['360px', '200px'],
                    content: '<form class="layui-form" style="padding:20px;" lay-filter="moveGroupForm">'
                        + '<div class="layui-form-item"><label class="layui-form-label">目标分组</label>'
                        + '<div class="layui-input-block"><select name="group_id">' + options + '</select></div></div>'
                        + '<div class="layui-form-item" style="text-align:right;margin-top:16px;">'
                        + '<button type="button" class="layui-btn layui-btn-primary" id="moveCancelBtn">取消</button> '
                        + '<button type="button" class="layui-btn" id="moveSubmitBtn">确定</button></div></form>',
                    success: function(layero) {
                        form.render('select', 'moveGroupForm');
                        layero.find('#moveCancelBtn').on('click', function() { layer.closeAll(); });
                        layero.find('#moveSubmitBtn').on('click', function() {
                            var groupId = layero.find('select[name=group_id]').val() || null;
                            $.ajax({
                                url: '/api/admin/attachments/move-group', type: 'PUT', dataType: 'json',
                                contentType: 'application/json',
                                data: JSON.stringify({ ids: ids, group_id: groupId }),
                                success: function(res) {
                                    if (res.code === 0) {
                                        layer.msg('移动成功', { icon: 1, time: 1000 });
                                        layer.closeAll();
                                        table.reload('att-table');
                                        loadGroups();
                                    } else {
                                        layer.msg(res.message || '移动失败', { icon: 2 });
                                    }
                                },
                                error: function() { layer.msg('请求失败', { icon: 2 }); }
                            });
                        });
                    }
                });
            });
        }
    });
</script>
</body>
</html>
