js分类筛查

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>技术人员状态与级别筛选</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#36D399',
                        warning: '#FFAA33',
                        neutral: {
                            100: '#F5F7FA',
                            200: '#E5E6EB',
                            300: '#C9CDD4',
                            400: '#86909C',
                            500: '#4E5969',
                            600: '#272E3B',
                            700: '#1D2129',
                        }
                    },
                    fontFamily: {
                        inter: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .tab-active {
                @apply text-primary border-primary font-medium;
            }
            .card-hover {
                @apply transition-all duration-300 hover:shadow-lg hover:-translate-y-1;
            }
            .fade-in {
                animation: fadeIn 0.5s ease-in-out;
            }
            @keyframes fadeIn {
                from { opacity: 0; transform: translateY(10px); }
                to { opacity: 1; transform: translateY(0); }
            }
        }
    </style>
</head>
<body class="bg-neutral-100 font-inter text-neutral-700 min-h-screen">
    <div class="container mx-auto px-4 py-8 max-w-6xl">
        <header class="mb-8 text-center">
            <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold text-neutral-700 mb-2">技术人员状态与级别筛选</h1>
            <p class="text-neutral-500 text-lg">根据技术人员的当前状态和级别进行快速筛选和查看</p>
        </header>

        <div class="bg-white rounded-xl shadow-md p-6 mb-8">
            <div class="flex flex-col md:flex-row md:items-center justify-between mb-6">
                <div class="mb-4 md:mb-0">
                    <h2 class="text-xl font-semibold text-neutral-700">技术人员列表</h2>
                    <p class="text-neutral-500">实时查看技术人员工作状态和级别</p>
                </div>
                <div class="flex space-x-2">
                    <div class="relative">
                        <input type="text" id="search-input" placeholder="搜索技术人员..." 
                            class="pl-10 pr-4 py-2 border border-neutral-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50 w-full md:w-64 transition-all">
                        <i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-neutral-400"></i>
                    </div>
                    <button id="refresh-btn" class="bg-primary text-white px-4 py-2 rounded-lg flex items-center transition-all hover:bg-primary/90">
                        <i class="fa fa-refresh mr-2"></i>刷新
                    </button>
                </div>
            </div>

            <!-- 状态选项卡 -->
            <div class="border-b border-neutral-200 mb-6">
                <div class="flex flex-wrap -mb-px">
                    <button id="tab-all" class="tab-btn tab-active inline-block py-4 px-6 text-sm font-medium text-center border-b-2 border-transparent rounded-t-lg hover:text-primary hover:border-primary/30 transition-all">
                        全部
                    </button>
                    <button id="tab-busy" class="tab-btn inline-block py-4 px-6 text-sm font-medium text-center border-b-2 border-transparent rounded-t-lg hover:text-primary hover:border-primary/30 transition-all">
                        <span class="inline-flex items-center">
                            <span class="w-2 h-2 bg-warning rounded-full mr-2"></span>在忙
                        </span>
                    </button>
                    <button id="tab-free" class="tab-btn inline-block py-4 px-6 text-sm font-medium text-center border-b-2 border-transparent rounded-t-lg hover:text-primary hover:border-primary/30 transition-all">
                        <span class="inline-flex items-center">
                            <span class="w-2 h-2 bg-secondary rounded-full mr-2"></span>空闲
                        </span>
                    </button>
                </div>
            </div>

            <!-- 级别筛选器 -->
            <div class="mb-6 flex flex-wrap gap-2">
                <button class="level-btn bg-primary text-white px-4 py-2 rounded-full text-sm flex items-center transition-all hover:bg-primary/90" data-level="all">
                    全部级别
                </button>
                <button class="level-btn bg-neutral-200 text-neutral-700 px-4 py-2 rounded-full text-sm flex items-center transition-all hover:bg-neutral-300" data-level="初级助教">
                    初级助教
                </button>
                <button class="level-btn bg-neutral-200 text-neutral-700 px-4 py-2 rounded-full text-sm flex items-center transition-all hover:bg-neutral-300" data-level="中级助教">
                    中级助教
                </button>
                <button class="level-btn bg-neutral-200 text-neutral-700 px-4 py-2 rounded-full text-sm flex items-center transition-all hover:bg-neutral-300" data-level="高级助教">
                    高级助教
                </button>
            </div>

            <!-- 技术人员列表 -->
            <div id="technician-list" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                <!-- 技术人员卡片将通过JavaScript动态生成 -->
            </div>

            <!-- 无数据状态 -->
            <div id="empty-state" class="hidden flex-col items-center justify-center py-16 text-center">
                <div class="w-24 h-24 bg-neutral-100 rounded-full flex items-center justify-center mb-4">
                    <i class="fa fa-users text-neutral-300 text-4xl"></i>
                </div>
                <h3 class="text-xl font-medium text-neutral-500 mb-2">暂无符合条件的技术人员</h3>
                <p class="text-neutral-400 max-w-md">请尝试调整筛选条件或刷新页面</p>
            </div>
        </div>
    </div>

    <footer class="bg-neutral-700 text-white py-8">
        <div class="container mx-auto px-4 max-w-6xl">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <h2 class="text-xl font-bold mb-2">技术人员管理系统</h2>
                    <p class="text-neutral-300 text-sm">实时监控技术人员状态,高效分配工作任务</p>
                </div>
                <div class="flex space-x-4">
                    <a href="#" class="text-neutral-300 hover:text-white transition-colors">
                        <i class="fa fa-question-circle mr-1"></i>帮助中心
                    </a>
                    <a href="#" class="text-neutral-300 hover:text-white transition-colors">
                        <i class="fa fa-cog mr-1"></i>系统设置
                    </a>
                    <a href="#" class="text-neutral-300 hover:text-white transition-colors">
                        <i class="fa fa-user-circle mr-1"></i>联系我们
                    </a>
                </div>
            </div>
            <div class="border-t border-neutral-600 mt-6 pt-6 text-center text-neutral-400 text-sm">
                © 2025 技术人员管理系统. 保留所有权利.
            </div>
        </div>
    </footer>

    <script>
        // 模拟接口数据
        const technicianData = [
            {
                "id": 555,
                "technicianname": "助教测试员1",
                "pricetype": 2,
                "price": 20.00,
                "overminute": 10,
                "hourreward": 25,
                "isdeleted": 0,
                "adduserid": 1,
                "addtime": "2025-04-03T01:06:44.000+00:00",
                "edituserid": 1,
                "edittime": "2025-04-28T02:47:09.000+00:00",
                "donglecode": "1130511145",
                "regrettime": 5,
                "timingunit": 1,
                "totaltimeover": 1,
                "startprice": 0.00,
                "techweixinid": null,
                "techtel": "13501012222",
                "techorder": 1,
                "overworkprice": 10.00,
                "overworkhourreward": 0.00,
                "techlevelname": "中级助教",
                "techteamname": "TOP团队",
                "smallticketno": "167434",
                "technicianid": 555,
                "starttime": "2025-04-28 10:35",
                "endtime": null,
                "trainingmoney": 0.00,
                "oneprice": null,
                "timelong": 0,
                "rewardmoney": 0,
                "techplaytype": 0,
                "totalminutes": 0,
                "techpausestarttime": null,
                "techpauseseconds": 0,
                "techfreeminutes": 0
            },
            {
                "id": 556,
                "technicianname": "助教测试员2",
                "pricetype": 1,
                "price": 25.00,
                "overminute": 15,
                "hourreward": 30,
                "isdeleted": 0,
                "adduserid": 1,
                "addtime": "2025-04-05T12:30:22.000+00:00",
                "edituserid": 1,
                "edittime": "2025-04-29T09:15:33.000+00:00",
                "donglecode": "1130511146",
                "regrettime": 8,
                "timingunit": 1,
                "totaltimeover": 0,
                "startprice": 5.00,
                "techweixinid": "wxid_123456",
                "techtel": "13501012223",
                "techorder": 2,
                "overworkprice": 15.00,
                "overworkhourreward": 5.00,
                "techlevelname": "高级助教",
                "techteamname": "精英团队",
                "smallticketno": "167435",
                "technicianid": 556,
                "starttime": "2025-04-29 08:45",
                "endtime": "2025-04-29 12:45",
                "trainingmoney": 0.00,
                "oneprice": null,
                "timelong": 4,
                "rewardmoney": 120,
                "techplaytype": 1,
                "totalminutes": 240,
                "techpausestarttime": null,
                "techpauseseconds": 0,
                "techfreeminutes": 15
            },
            {
                "id": 557,
                "technicianname": "助教测试员3",
                "pricetype": 2,
                "price": 18.00,
                "overminute": 8,
                "hourreward": 20,
                "isdeleted": 0,
                "adduserid": 1,
                "addtime": "2025-04-10T08:15:45.000+00:00",
                "edituserid": 1,
                "edittime": "2025-04-28T14:20:15.000+00:00",
                "donglecode": "1130511147",
                "regrettime": 3,
                "timingunit": 2,
                "totaltimeover": 1,
                "startprice": 0.00,
                "techweixinid": null,
                "techtel": "13501012224",
                "techorder": 3,
                "overworkprice": 8.00,
                "overworkhourreward": 0.00,
                "techlevelname": "初级助教",
                "techteamname": "TOP团队",
                "smallticketno": "167436",
                "technicianid": 557,
                "starttime": "2025-04-28 14:30",
                "endtime": null,
                "trainingmoney": 0.00,
                "oneprice": null,
                "timelong": 0,
                "rewardmoney": 0,
                "techplaytype": 0,
                "totalminutes": 0,
                "techpausestarttime": null,
                "techpauseseconds": 0,
                "techfreeminutes": 0
            },
            {
                "id": 558,
                "technicianname": "助教测试员4",
                "pricetype": 1,
                "price": 30.00,
                "overminute": 20,
                "hourreward": 35,
                "isdeleted": 0,
                "adduserid": 1,
                "addtime": "2025-04-15T16:40:30.000+00:00",
                "edituserid": 1,
                "edittime": "2025-04-29T11:10:25.000+00:00",
                "donglecode": "1130511148",
                "regrettime": 10,
                "timingunit": 1,
                "totaltimeover": 1,
                "startprice": 8.00,
                "techweixinid": "wxid_789012",
                "techtel": "13501012225",
                "techorder": 4,
                "overworkprice": 20.00,
                "overworkhourreward": 10.00,
                "techlevelname": "高级助教",
                "techteamname": "精英团队",
                "smallticketno": "167437",
                "technicianid": 558,
                "starttime": "2025-04-29 10:00",
                "endtime": "2025-04-29 13:30",
                "trainingmoney": 0.00,
                "oneprice": null,
                "timelong": 3.5,
                "rewardmoney": 122.5,
                "techplaytype": 1,
                "totalminutes": 210,
                "techpausestarttime": null,
                "techpauseseconds": 0,
                "techfreeminutes": 20
            },
            {
                "id": 559,
                "technicianname": "助教测试员5",
                "pricetype": 2,
                "price": 22.00,
                "overminute": 12,
                "hourreward": 28,
                "isdeleted": 0,
                "adduserid": 1,
                "addtime": "2025-04-20T09:25:18.000+00:00",
                "edituserid": 1,
                "edittime": "2025-04-29T14:50:40.000+00:00",
                "donglecode": "1130511149",
                "regrettime": 6,
                "timingunit": 1,
                "totaltimeover": 0,
                "startprice": 0.00,
                "techweixinid": null,
                "techtel": "13501012226",
                "techorder": 5,
                "overworkprice": 12.00,
                "overworkhourreward": 0.00,
                "techlevelname": "中级助教",
                "techteamname": "TOP团队",
                "smallticketno": "167438",
                "technicianid": 559,
                "starttime": "2025-04-29 15:00",
                "endtime": null,
                "trainingmoney": 0.00,
                "oneprice": null,
                "timelong": 0,
                "rewardmoney": 0,
                "techplaytype": 0,
                "totalminutes": 0,
                "techpausestarttime": null,
                "techpauseseconds": 0,
                "techfreeminutes": 0
            }
        ];

        // 当前筛选状态
        let currentFilters = {
            status: 'all', // all, busy, free
            level: 'all'   // all, 初级助教, 中级助教, 高级助教
        };

        // 初始化页面
        document.addEventListener('DOMContentLoaded', () => {
            // 渲染技术人员列表
            renderTechnicianList(technicianData);
            
            // 状态选项卡点击事件
            document.querySelectorAll('.tab-btn').forEach(btn => {
                btn.addEventListener('click', () => {
                    // 移除所有选项卡的活跃状态
                    document.querySelectorAll('.tab-btn').forEach(tab => {
                        tab.classList.remove('tab-active');
                    });
                    
                    // 添加当前选项卡的活跃状态
                    btn.classList.add('tab-active');
                    
                    // 更新筛选状态
                    if (btn.id === 'tab-all') {
                        currentFilters.status = 'all';
                    } else if (btn.id === 'tab-busy') {
                        currentFilters.status = 'busy';
                    } else if (btn.id === 'tab-free') {
                        currentFilters.status = 'free';
                    }
                    
                    // 重新渲染列表
                    filterAndRenderTechnicians();
                });
            });
            
            // 级别筛选按钮点击事件
            document.querySelectorAll('.level-btn').forEach(btn => {
                btn.addEventListener('click', () => {
                    // 移除所有级别按钮的活跃状态
                    document.querySelectorAll('.level-btn').forEach(levelBtn => {
                        levelBtn.classList.remove('bg-primary', 'text-white');
                        levelBtn.classList.add('bg-neutral-200', 'text-neutral-700');
                    });
                    
                    // 添加当前级别按钮的活跃状态
                    btn.classList.remove('bg-neutral-200', 'text-neutral-700');
                    btn.classList.add('bg-primary', 'text-white');
                    
                    // 更新筛选状态
                    currentFilters.level = btn.dataset.level;
                    
                    // 重新渲染列表
                    filterAndRenderTechnicians();
                });
            });
            
            // 搜索输入事件
            const searchInput = document.getElementById('search-input');
            searchInput.addEventListener('input', debounce(function() {
                const searchTerm = this.value.toLowerCase().trim();
                filterAndRenderTechnicians(searchTerm);
            }, 300));
            
            // 刷新按钮点击事件
            document.getElementById('refresh-btn').addEventListener('click', function() {
                // 添加旋转动画
                this.querySelector('i').classList.add('fa-spin');
                
                // 模拟加载
                setTimeout(() => {
                    // 恢复图标
                    this.querySelector('i').classList.remove('fa-spin');
                    
                    // 刷新列表
                    filterAndRenderTechnicians();
                    
                    // 显示刷新成功提示
                    showToast('数据已刷新');
                }, 800);
            });
        });

        // 防抖函数
        function debounce(func, wait) {
            let timeout;
            return function() {
                const context = this;
                const args = arguments;
                clearTimeout(timeout);
                timeout = setTimeout(() => func.apply(context, args), wait);
            };
        }

        // 筛选并渲染技术人员列表
        function filterAndRenderTechnicians(searchTerm = '') {
            let filteredTechnicians = technicianData;
            
            // 应用状态筛选
            if (currentFilters.status === 'busy') {
                filteredTechnicians = filteredTechnicians.filter(tech => tech.endtime === null);
            } else if (currentFilters.status === 'free') {
                filteredTechnicians = filteredTechnicians.filter(tech => tech.endtime !== null);
            }
            
            // 应用级别筛选
            if (currentFilters.level !== 'all') {
                filteredTechnicians = filteredTechnicians.filter(tech => tech.techlevelname === currentFilters.level);
            }
            
            // 应用搜索筛选
            if (searchTerm) {
                filteredTechnicians = filteredTechnicians.filter(tech => 
                    tech.technicianname.toLowerCase().includes(searchTerm) ||
                    tech.techlevelname.toLowerCase().includes(searchTerm) ||
                    tech.techteamname.toLowerCase().includes(searchTerm) ||
                    (tech.techtel && tech.techtel.includes(searchTerm))
                );
            }
            
            // 渲染筛选后的列表
            renderTechnicianList(filteredTechnicians);
        }

        // 渲染技术人员列表
        function renderTechnicianList(technicians) {
            const listElement = document.getElementById('technician-list');
            const emptyState = document.getElementById('empty-state');
            
            // 清空列表
            listElement.innerHTML = '';
            
            // 检查是否有数据
            if (technicians.length === 0) {
                emptyState.classList.remove('hidden');
                return;
            }
            
            // 隐藏空状态
            emptyState.classList.add('hidden');
            
            // 渲染每个技术人员卡片
            technicians.forEach(tech => {
                const card = createTechnicianCard(tech);
                listElement.appendChild(card);
            });
        }

        // 创建技术人员卡片
        function createTechnicianCard(tech) {
            const isBusy = tech.endtime === null;
            const statusText = isBusy ? '在忙' : '空闲';
            const statusColor = isBusy ? 'bg-warning text-white' : 'bg-secondary text-white';
            const statusIcon = isBusy ? 'fa-circle text-warning' : 'fa-circle text-secondary';
            
            // 创建卡片元素
            const card = document.createElement('div');
            card.className = `bg-white rounded-xl shadow-sm overflow-hidden card-hover fade-in`;
            card.innerHTML = `
                <div class="p-6">
                    <div class="flex justify-between items-start mb-4">
                        <div>
                            <h3 class="text-lg font-semibold text-neutral-700">${tech.technicianname}</h3>
                            <div class="flex items-center mt-1">
                                <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getLevelColor(tech.techlevelname)}">
                                    ${tech.techlevelname}
                                </span>
                                <span class="ml-2 text-xs text-neutral-500">${tech.techteamname}</span>
                            </div>
                        </div>
                        <div class="flex items-center">
                            <i class="fa ${statusIcon} mr-1"></i>
                            <span class="text-sm font-medium ${isBusy ? 'text-warning' : 'text-secondary'}">${statusText}</span>
                        </div>
                    </div>
                    
                    <div class="grid grid-cols-2 gap-4 mb-4 text-sm">
                        <div class="flex flex-col">
                            <span class="text-neutral-500">工号</span>
                            <span class="font-medium">${tech.smallticketno}</span>
                        </div>
                        <div class="flex flex-col">
                            <span class="text-neutral-500">电话</span>
                            <span class="font-medium">${tech.techtel}</span>
                        </div>
                        <div class="flex flex-col">
                            <span class="text-neutral-500">服务价格</span>
                            <span class="font-medium">¥${tech.price}/小时</span>
                        </div>
                        <div class="flex flex-col">
                            <span class="text-neutral-500">开始时间</span>
                            <span class="font-medium">${formatDateTime(tech.starttime)}</span>
                        </div>
                    </div>
                    
                    ${isBusy ? 
                        `<div class="p-3 bg-neutral-50 rounded-lg mb-4">
                            <div class="flex justify-between items-center">
                                <span class="text-sm text-neutral-500">当前服务时长</span>
                                <span class="text-sm font-medium">${calculateServiceDuration(tech.starttime)} 小时</span>
                            </div>
                        </div>` : 
                        `<div class="p-3 bg-neutral-50 rounded-lg mb-4">
                            <div class="flex justify-between items-center">
                                <span class="text-sm text-neutral-500">最近服务时长</span>
                                <span class="text-sm font-medium">${tech.timelong} 小时</span>
                            </div>
                            <div class="flex justify-between items-center mt-2">
                                <span class="text-sm text-neutral-500">结束时间</span>
                                <span class="text-sm font-medium">${formatDateTime(tech.endtime)}</span>
                            </div>
                        </div>`
                    }
                    
                    <div class="flex space-x-2">
                        <button class="flex-1 bg-primary hover:bg-primary/90 text-white py-2 rounded-lg transition-all flex items-center justify-center">
                            <i class="fa fa-phone mr-2"></i>联系
                        </button>
                        <button class="w-10 h-10 flex items-center justify-center border border-neutral-200 rounded-lg hover:bg-neutral-50 transition-all">
                            <i class="fa fa-ellipsis-v text-neutral-500"></i>
                        </button>
                    </div>
                </div>
            `;
            
            return card;
        }

        // 获取级别对应的颜色
        function getLevelColor(level) {
            switch(level) {
                case '初级助教':
                    return 'bg-blue-100 text-blue-800';
                case '中级助教':
                    return 'bg-green-100 text-green-800';
                case '高级助教':
                    return 'bg-purple-100 text-purple-800';
                default:
                    return 'bg-neutral-100 text-neutral-800';
            }
        }

        // 格式化日期时间
        function formatDateTime(dateTime) {
            if (!dateTime) return 'N/A';
            
            // 处理ISO格式和非ISO格式
            let date;
            if (dateTime.includes('T')) {
                date = new Date(dateTime);
            } else {
                // 尝试解析非ISO格式
                const parts = dateTime.split(/[- :]/);
                date = new Date(parts[0], parts[1]-1, parts[2], parts[3], parts[4]);
            }
            
            return date.toLocaleString('zh-CN', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit'
            });
        }

        // 计算服务时长
        function calculateServiceDuration(startTime) {
            if (!startTime) return '0';
            
            const start = new Date(startTime.includes('T') ? startTime : startTime.replace(' ', 'T'));
            const now = new Date();
            const diffMs = now - start;
            const diffHours = Math.round(diffMs / (1000 * 60 * 60) * 10) / 10; // 保留一位小数
            
            return Math.max(0, diffHours).toFixed(1);
        }

        // 显示提示消息
        function showToast(message) {
            // 创建提示元素
            const toast = document.createElement('div');
            toast.className = 'fixed bottom-4 right-4 bg-neutral-700 text-white px-4 py-2 rounded-lg shadow-lg z-50 transform transition-all duration-300 opacity-0 translate-y-4';
            toast.textContent = message;
            
            // 添加到页面
            document.body.appendChild(toast);
            
            // 显示动画
            setTimeout(() => {
                toast.classList.remove('opacity-0', 'translate-y-4');
            }, 10);
            
            // 自动隐藏
            setTimeout(() => {
                toast.classList.add('opacity-0', 'translate-y-4');
                setTimeout(() => {
                    document.body.removeChild(toast);
                }, 300);
            }, 3000);
        }
    </script>
</body>
</html>
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尔嵘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值