KJL后台-商品列表页查看自定义属性和参数
// ==UserScript==
// @name KJL后台-商品列表页查看自定义属性和参数
// @namespace Violentmonkey Scripts
// @match https://www.kujiale.com/pub/saas/admin/brandgoods/all*
// @match https://www.kujiale.com/pub/saas/workbench/brandgoods/all*
// @grant none
// @version 1.0
// @author hejie13250
// @description 2025/2/26 10:15:58
// ==/UserScript==
(function() {
'use strict';
// 添加样式到文档
var style = document.createElement('style');
document.head.appendChild(style);
style.type = 'text/css';
style.appendChild(document.createTextNode(`
tr.StyledBodyRowTr-kSBvgt td:nth-child(1),
tr.StyledBodyRowTr-kSBvgt td:nth-child(2),
tr.StyledBodyRowTr-kSBvgt td:nth-last-child(2),
tr.StyledBodyRowTr-kSBvgt td:nth-last-child(1) {
cursor: default;
}
tr.StyledBodyRowTr-kSBvgt > td {
padding: 0px 5px !important;
}
.Link-qfJUS.dtwGsR {
padding: 6px 6px;
}
.fnmwsn {
margin-bottom: 0px;
}
.djGvpx:hover {
background: #9d8b889c;
}
`));
// 防止表格前两列和后两列误点击
// document.querySelectorAll('tr.StyledBodyRowTr-kSBvgt td:nth-child(1), tr.StyledBodyRowTr-kSBvgt td:nth-child(2), tr.StyledBodyRowTr-kSBvgt td:nth-last-child(2), tr.StyledBodyRowTr-kSBvgt td:nth-last-child(1)').forEach(td => {
// td.addEventListener('click', function(e) {
// e.preventDefault();
// e.stopPropagation();
// });
// });
var DEBUG_MODE = true // 调试模式
let idColumnIndex = null; // 动态ID列索引
// 调试日志
function log(...args) {
if (DEBUG_MODE) console.log('[KUJIALE]', ...args);
}
// 初始化ID列索引
function initIdColumnIndex() {
const headerRow = document.querySelector('.StyledTable-diJSpn > thead:nth-child(2) > tr');
if (!headerRow) {
log('表头行未找到');
return false;
}
const headers = headerRow.querySelectorAll('th');
for (let i = 0; i < headers.length; i++) {
if (headers[i].textContent.includes('商品ID')) {
idColumnIndex = i + 1;
log('ID列索引:', idColumnIndex);
return true;
}
}
log('未找到"商品ID"列');
return false;
}
// 创建浮动窗口
function createFloatingWindow() {
const modalMask = document.createElement('div');
modalMask.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:999;display:none;';
const modalContent = document.createElement('div');
modalContent.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:500px;height:600px;background:white;border-radius:8px;padding:20px;overflow:hidden;box-shadow:0 4px 12px rgba(0,0,0,0.15);';
const tablesContainer = document.createElement('div');
tablesContainer.style.cssText = 'height:560px;overflow:auto;';
modalContent.appendChild(tablesContainer);
modalMask.appendChild(modalContent);
document.body.appendChild(modalMask);
// 点击遮罩层关闭窗口
modalMask.addEventListener('click', (e) => {
if (e.target === modalMask) {
modalMask.style.display = 'none';
}
});
return { modalMask, tablesContainer };
}
// 创建并显示浮动窗口
const { modalMask, tablesContainer } = createFloatingWindow();
function createTable(title, columns, rows) {
const table = document.createElement('table');
table.style.cssText = 'width:100%;margin-top:20px;border-collapse:collapse;font-size:14px;';
const thead = document.createElement('thead');
thead.innerHTML = `<tr>${columns.map(col => `<th style="border:1px solid #ddd;padding:8px;background:#f5f5f5;">${col}</th>`).join('')}</tr>`;
const tbody = document.createElement('tbody');
rows.forEach(row => {
const tr = document.createElement('tr');
tr.innerHTML = row.map(cell => `<td style="border:1px solid #ddd;padding:8px;">${cell}</td>`).join('');
tbody.appendChild(tr);
});
table.appendChild(thead);
table.appendChild(tbody);
const wrapper = document.createElement('div');
wrapper.style.marginTop = '20px';
const titleEl = document.createElement('h3');
titleEl.textContent = title;
titleEl.style.cssText = 'font-size:16px;margin:0 0 10px 0;color:#333;';
wrapper.appendChild(titleEl);
wrapper.appendChild(table);
return wrapper;
}
function getData(obsBgId) {
tablesContainer.innerHTML = '<div style="text-align:center;padding:20px;">加载中...</div>';
Promise.allSettled([
fetch(`https://www.kujiale.com/editor/api/site/param/bizproperty/editordata/query?obsBrandGoodId=${obsBgId}`)
.then(r => r.json()),
fetch(`https://www.kujiale.com/dcscms/api/custom/brandgood/attribute?start=0&num=30&obsBgId=${obsBgId}`)
.then(r => r.json()),
fetch(`https://www.kujiale.com/editor/api/site/input/parameters/${obsBgId}`)
.then(r => r.json())
]).then(responses => {
tablesContainer.innerHTML = '';
responses.forEach((response, index) => {
if (response.status !== 'fulfilled') return;
const data = response.value;
let title = '', columns = [], rows = [];
switch(index) {
case 0: // 自定义输出属性
if (data?.d?.length > 0) {
title = '自定义输出属性';
columns = ['属性名称', '属性引用名', '属性值'];
rows = data.d.map(item => [item.name, item.key, item.value]);
}
break;
case 1: // 自定义属性
if (data?.d?.result?.length > 0) {
title = '自定义属性';
columns = ['属性名称', '属性引用名', '属性值'];
rows = data.d.result.map(item => [item.attributeName, item.quoteName, item.attributeValue]);
}
break;
case 2: // 自定义参数
if (Array.isArray(data) && data.length > 0) {
title = '自定义参数';
columns = ['参数名称', '参数引用名'];
rows = data.map(item => [item.displayName, item.paramName]);
}
break;
}
if (title && columns.length > 0) {
tablesContainer.appendChild(createTable(title, columns, rows));
}
});
modalMask.style.display = tablesContainer.children.length > 0 ? 'block' : 'none';
});
}
// 通用按钮创建函数
function createButton() {
const btn = document.createElement('div');
btn.className = 'custom-update-btn';
btn.style.cssText = 'display: inline-block;';
const link = document.createElement('a');
link.className = 'StyledLink-kjrCJO gvhEJs StyledInlineButton-fyUImi djGvpx WrapInlineButton-nnTTR kUBFEP Link-qfJUS dtwGsR';
link.style.cssText = 'cursor: pointer; color: rgb(51, 139, 255);';
link.textContent = '查看属性';
// 点击事件处理
link.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
// 向上查找数据行,获取商口ID,
const row = this.closest('tr.StyledBodyRowTr-kSBvgt');
if (!row) {
log('未找到数据行元素');
return;
}
// 动态获取ID列
const idCell = row.querySelector(`td:nth-child(${idColumnIndex})`);
if (!idCell) {
log('ID列元素不存在');
return;
}
// 兼容多层嵌套内容
const actualElement = idCell.querySelector('span, div') || idCell;
const currentId = (actualElement.textContent || '').trim();
if (!currentId) {
log('获取到空ID');
return;
}
log('成功获取当前商品的ID:', currentId);
getData(currentId);
});
btn.appendChild(link);
return btn;
}
// 按钮注入逻辑
function addButtons() {
if (idColumnIndex === null) {
if (!initIdColumnIndex()) {
log('无法初始化ID列索引,按钮注入中止');
return;
}
}
document.querySelectorAll('tr.StyledBodyRowTr-kSBvgt').forEach(row => {
const targetTd = row.querySelector(`td:nth-child(2) > div:nth-child(1) > div:nth-child(2) > div:nth-child(1)`);
if (!targetTd) {
log('目标单元格不存在');
return;
}
// 使用更稳定的容器选择方式
const container = targetTd.querySelector('div:first-child');
if (container && !container.querySelector('.custom-update-btn')) {
container.append(createButton());
log('按钮注入成功');
}
});
}
// DOM观察器,监听表格动态加载
const observer = new MutationObserver(mutations => {
if (document.querySelector('tr.StyledBodyRowTr-kSBvgt')) {
addButtons();
}
});
// 启动观察
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: false
});
// 初始执行
if (document.readyState === 'complete') {
addButtons();
} else {
window.addEventListener('load', addButtons);
}
})();