Greasy Fork is available in English.

油猴5-IMMS检查检项状态(动态更新)

获取前20个批号并动态更新检项完成状态

// ==UserScript==
// @name         油猴5-IMMS检查检项状态(动态更新)
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  获取前20个批号并动态更新检项完成状态
// @author       Your Name
// @match        http://192.168.100.113/pcis/a/index*
// @grant        GM_xmlhttpRequest
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 初始化 container
    let container = null;

    // 创建主按钮
    const mainButton = document.createElement('button');
    mainButton.textContent = '检查前20批';
    mainButton.style.position = 'fixed';
    mainButton.style.top = '111px'; // 原为 '61px',下移 50px
    mainButton.style.left = '58px'; // 主按钮位置
    mainButton.style.zIndex = '3000';
    mainButton.classList.add("effect2");

    // 定义检项按钮的简化名称与详细名称映射表
    const inspectionMapping = [
        { id: '0', simplified: '鉴别', detailed: '鉴别试验' },
        { id: '1', simplified: '外观', detailed: '外观' },
        { id: '2', simplified: '渗透', detailed: '渗透压摩尔浓度' },
        { id: '3', simplified: 'pH值', detailed: 'pH值' },
        { id: '4', simplified: '水分', detailed: '水分' },
        { id: '5', simplified: '效价', detailed: '效价测定' },
        { id: '6', simplified: '热稳', detailed: '热稳定性试验' },
        { id: '7', simplified: '牛残', detailed: '牛血清白蛋白残留量' },
        { id: '8', simplified: '蛋残', detailed: 'Vero细胞蛋白质残留量' },
        { id: '9', simplified: '无菌', detailed: '无菌检查' },
        { id: '10', simplified: '异毒', detailed: '异常毒性检查' },
        { id: '11', simplified: '内毒', detailed: '细菌内毒素检查' }
    ];

    // 创建检项按钮容器
    const inspectionContainer = document.createElement('div');
    inspectionContainer.style.position = 'fixed';
    inspectionContainer.style.top = '111px'; // 原为 '61px',下移 50px
    inspectionContainer.style.left = '160px'; // 检项按钮位置(避开主按钮)
    inspectionContainer.style.display = 'flex';
    inspectionContainer.style.flexDirection = 'row';
    inspectionContainer.style.alignItems = 'center';
    inspectionContainer.style.zIndex = '3000';

    // 添加检项按钮
    inspectionMapping.forEach(item => {
        const button = document.createElement('button');
        button.textContent = item.simplified; // 显示简化名称
        button.style.width = '50px'; // 统一宽度为50px
        button.style.height = '25px';
        button.style.borderRadius = '5px';
        button.style.backgroundColor = '#f0f0f0';
        button.style.cursor = 'default';
        button.style.boxShadow = '1px 1px 2px rgba(0, 0, 0, 0.1)';
        button.style.margin = '0'; // 移除间距
        inspectionContainer.appendChild(button);
    });

    // 将悬浮按钮和检项按钮添加到页面上
    document.body.appendChild(inspectionContainer);
    document.body.appendChild(mainButton);

    // 发送POST请求的函数
    function sendPostRequest() {
        const url = 'http://192.168.100.113/pcis/a/lims/sampling/limsTestOrderManual/listData';
        const data = 'reqCode=vp&pageNo=1&reqOrgOffice.officeName=%E7%8B%82%E7%8A%AC%E8%8B%97%E5%88%B6%E5%89%82%E8%BD%A6%E9%97%B4&reqOrg=SDJN01002&orderBy=a.own_batch+desc';
        const head = { 'Content-Type': 'application/x-www-form-urlencoded' };

        GM_xmlhttpRequest({
            method: 'POST',
            url: url,
            data: data,
            headers: head,
            onload: function(response) {
                try {
                    const jsonResponse = JSON.parse(response.responseText);
                    if (typeof jsonResponse === 'object' && jsonResponse.list && Array.isArray(jsonResponse.list)) {
                        const items = jsonResponse.list.slice(0, 20); // 获取前20批

                        // 确保移除旧的 container
                        if (container) {
                            document.body.removeChild(container);
                        }

                        // 创建一个新的 container
                        container = document.createElement('div');
                        container.style.position = 'fixed';
                        container.style.top = `${parseInt(mainButton.style.top) + 25}px`; // 下移 50px 后调整相对位置
                        container.style.left = mainButton.style.left; // 对齐主按钮
                        container.style.zIndex = '3000';
                        container.style.display = 'flex';
                        container.style.flexDirection = 'column';

                        // 存储行级容器以便后续更新
                        const batchRows = [];

                        items.forEach(item => {
                            const batchRow = document.createElement('div');
                            batchRow.style.display = 'flex';
                            batchRow.style.alignItems = 'center';
                            //batchRow.style.marginBottom = '5px'; // 行间距

                            // 批号按钮
                            const batchButton = document.createElement('button');
                            batchButton.textContent = item.ownBatch;
                            batchButton.style.width = '100px'; // 批号按钮宽度保持不变
                            batchButton.style.height = '25px';
                            batchButton.style.borderRadius = '5px';
                            batchButton.style.backgroundColor = '#f9f9f9';
                            batchButton.style.boxShadow = '1px 1px 2px rgba(0, 0, 0, 0.1)';
                            batchButton.style.cursor = 'default';
                            batchRow.appendChild(batchButton);

                            // 中间状态按钮
                            const statusButtons = [];
                            inspectionMapping.forEach(() => {
                                const statusButton = document.createElement('button');
                                statusButton.textContent = '加载中...';
                                statusButton.style.width = '50px'; // 状态按钮宽度为50px
                                statusButton.style.height = '25px';
                                statusButton.style.borderRadius = '5px';
                                statusButton.style.backgroundColor = '#eaeaea';
                                statusButton.style.boxShadow = '1px 1px 2px rgba(0, 0, 0, 0.1)';
                                statusButton.style.margin = '0'; // 移除间距
                                statusButton.style.cursor = 'default';
                                statusButtons.push(statusButton);
                                batchRow.appendChild(statusButton);
                            });

                            batchRows.push({ row: batchRow, buttons: statusButtons });
                            container.appendChild(batchRow);

                            // 发送子请求获取 opStatus 数据
                            fetchInspectionStatus(item.id, statusButtons);
                        });

                        document.body.appendChild(container);
                    } else {
                        console.error('JSON响应结构不正确,无法找到list数组');
                        alert('JSON响应结构不正确,无法找到list数组');
                    }
                } catch (error) {
                    console.error('解析JSON失败:', error);
                    alert('解析JSON失败');
                }
            },
            onerror: function(response) {
                console.error('请求失败:', response);
                alert('请求失败');
            }
        });
    }

    // 发送子请求获取 opStatus 数据
    function fetchInspectionStatus(id, statusButtons) {
        const url = 'http://192.168.100.113/pcis/a/lims/inspectiontask/listData';
        const data = `inspectionId=${id}&inspectionItem=&startTimeRange=&_search=false&pageSize=-1&pageNo=1&orderBy=&sord=asc`;
        const head = { 'Content-Type': 'application/x-www-form-urlencoded' };

        GM_xmlhttpRequest({
            method: 'POST',
            url: url,
            data: data,
            headers: head,
            onload: function(response) {
                try {
                    const jsonResponse = JSON.parse(response.responseText);

                    // 创建一个映射表,用于将 detailed 名称映射到按钮索引
                    const itemMapping = {};
                    inspectionMapping.forEach((item, index) => {
                        itemMapping[item.detailed] = index;
                    });

                    // 遍历返回的 list 数据
                    if (jsonResponse.list && Array.isArray(jsonResponse.list)) {
                        jsonResponse.list.forEach(row => {
                            const itemName = row.inspectionItem; // 获取检项名称
                            const opStatus = row.opStatus; // 获取状态

                            // 查找对应的按钮索引
                            if (itemName in itemMapping) {
                                const index = itemMapping[itemName];
                                if (statusButtons[index]) {
                                    statusButtons[index].textContent = opStatus || '未知';
                                    statusButtons[index].style.backgroundColor = getOpStatusColor(opStatus);
                                }
                            } else {
                                console.warn(`未找到匹配的检项名称:${itemName}`);
                            }
                        });
                    } else {
                        console.warn(`ID ${id} 的数据为空或格式错误`);
                        alert(`ID ${id} 的数据为空或格式错误,请检查控制台日志以获取详细信息。`);
                    }
                } catch (error) {
                    console.error(`解析ID ${id}的数据失败,返回的原始数据为:`, response.responseText);
                    console.error(`解析错误详情:`, error);
                    alert(`解析ID ${id}的数据失败,请检查控制台日志以获取详细信息。`);
                }
            },
            onerror: function(response) {
                console.error(`请求ID ${id}的数据失败:`, response);
                alert(`请求ID ${id}的数据失败,请检查网络连接或服务器状态。`);
            }
        });
    }

    // 根据 opStatus 设置颜色
    function getOpStatusColor(opStatus) {
        switch (opStatus) {
            case '5':
                return '#a5d6a7'; // 绿色
            case '3':
                return '#ffe082'; // 黄色
            case '1':
                return '#ef9a9a'; // 红色
            default:
                return '#eaeaea'; // 默认灰色
        }
    }

    // 为悬浮按钮添加点击事件监听器
    mainButton.addEventListener('click', () => {
        sendPostRequest();
    });

    // 添加样式
    const style = document.createElement('style');
    style.textContent = `
        .effect2 {
            cursor: pointer;
            width: 99px;
            height: 25px;
            display: flex;
            justify-content: center;
            align-items: center;
            border: 1px solid pink;
            border-radius: 5px;
            box-shadow: 2px 2px 2px rgba(255,192,203,.4);
        }
    `;
    document.head.appendChild(style);
})();