diff --git a/apps/jingrow/frontend/src/core/pagetype/form/controls/Jeditor.vue b/apps/jingrow/frontend/src/core/pagetype/form/controls/Jeditor.vue index 468e33d..a215c25 100644 --- a/apps/jingrow/frontend/src/core/pagetype/form/controls/Jeditor.vue +++ b/apps/jingrow/frontend/src/core/pagetype/form/controls/Jeditor.vue @@ -974,5 +974,110 @@ watch(() => props.disabled, (disabled) => { max-width: 100% !important; width: auto !important; } + +/* 表格标准样式 */ +.jeditor table { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + margin: 12px 0; + overflow: hidden; + border: 1px solid #e5e7eb; + border-radius: 6px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); +} + +.jeditor table td, +.jeditor table th { + min-width: 1em; + padding: 8px 12px; + border: 1px solid #e5e7eb; + vertical-align: top; + box-sizing: border-box; + position: relative; + background-color: #fff; +} + +.jeditor table th { + font-weight: 600; + text-align: left; + background-color: #f8f9fa; + color: #374151; + border-bottom: 2px solid #e5e7eb; +} + +.jeditor table td { + background-color: #fff; + color: #1f2937; +} + +/* 表格选中状态 */ +.jeditor table .selectedCell:after { + z-index: 2; + position: absolute; + content: ""; + left: 0; right: 0; top: 0; bottom: 0; + background: rgba(31, 199, 111, 0.1); + pointer-events: none; +} + +.jeditor table .column-resize-handle { + position: absolute; + right: -2px; + top: 0; + bottom: -2px; + width: 4px; + background-color: #1fc76f; + pointer-events: none; + opacity: 0; + transition: opacity 0.2s ease; +} + +.jeditor table:hover .column-resize-handle, +.jeditor table .column-resize-handle.selected { + opacity: 1; +} + +/* 表格行悬浮效果 */ +.jeditor table tr:hover td { + background-color: #f9fafb; +} + +.jeditor table tr:hover th { + background-color: #f1f3f5; +} + +/* 表格响应式处理 */ +.jeditor .ProseMirror { + overflow-x: auto; +} + +/* 当表格过宽时,允许横向滚动 */ +.jeditor table { + max-width: 100%; + display: table; +} + +.jeditor table td, +.jeditor table th { + white-space: normal; + word-wrap: break-word; +} + +/* 表格编辑时的焦点样式 */ +.jeditor table td:focus, +.jeditor table th:focus { + outline: 2px solid #1fc76f; + outline-offset: -2px; +} + +/* 表格空单元格样式 */ +.jeditor table td p.is-editor-empty:first-child::before { + content: attr(data-placeholder); + float: left; + color: #adb5bd; + pointer-events: none; + height: 0; +} diff --git a/apps/jingrow/jingrow/ai/nodes/web_scrapers_create/web_scrapers_create.py b/apps/jingrow/jingrow/ai/nodes/web_scrapers_create/web_scrapers_create.py index 54a2aed..0e864c4 100644 --- a/apps/jingrow/jingrow/ai/nodes/web_scrapers_create/web_scrapers_create.py +++ b/apps/jingrow/jingrow/ai/nodes/web_scrapers_create/web_scrapers_create.py @@ -3,6 +3,7 @@ import re import asyncio import requests import uuid +import html from typing import Dict, Any, Optional, List from urllib.parse import urljoin, urlparse, parse_qs, urlencode @@ -516,17 +517,102 @@ def extract_product_title(soup): return '' +def convert_bsc_info_to_table(bsc_info): + """将 bsc-info 的 div 结构转换为表格格式""" + if not bsc_info: + return '' + + # 查找所有子区块 + subblocks = bsc_info.find_all('div', class_='sr-layout-subblock') + if not subblocks: + return '' + + html_parts = [] + + for subblock in subblocks: + # 提取标题 + title_elem = subblock.find('div', class_='sr-txt-title') + title = '' + if title_elem: + h2 = title_elem.find('h2') + if h2: + title = h2.get_text(strip=True) + + # 查找所有 bsc-item + content_div = subblock.find('div', class_='sr-layout-content') + if not content_div: + continue + + basic_info_list = content_div.find('div', class_='basic-info-list') + if not basic_info_list: + continue + + items = basic_info_list.find_all('div', class_='bsc-item') + if not items: + continue + + # 构建表格HTML + table_html = [] + if title: + title_escaped = html.escape(title) + table_html.append(f'
| ') + table_html.append(f'{label_text_escaped}: {value_text_escaped}') + table_html.append(' | ') + table_html.append('|
| {label_text_escaped} | ') + table_html.append(f'{value_text_escaped} | ') + table_html.append('