refactor(storefront): 价格表去HTML化改bricks声明式控件(用户2026-09-18纠正:不用Html拼table)——core.py只回结构化headers/rows(单元格{t,k}),index.ui用VBox/HBox+Text(tabular-header-row/tabular-row框架双主题类)渲染,价格红/原价划线var(--ink-3)+line-through;Jinja真渲染验JSON合法
This commit is contained in:
parent
637c729e90
commit
aee498de78
@ -1321,8 +1321,8 @@ class ProductManager:
|
||||
全表同因子(如 flat=按次)时省略——价格列单位(元/张)已表达口径
|
||||
|
||||
Returns:
|
||||
{'headers': [...], 'rows': [[要素值..., 价格文本]], 'html': '<table>…'}
|
||||
html 供 .ui 直接嵌入 Html 控件;让利(discount<1)时价格单元格附划线原价。
|
||||
{'headers': [...], 'rows': [[要素值..., {'t': 价格文本, 'k': 'price'}...]]}
|
||||
k='orig' 的单元格是划线原价(让利时附)。.ui 用声明式控件渲染(2026-09-18)。
|
||||
"""
|
||||
cols = [] # [(key, header)]
|
||||
seen = set()
|
||||
@ -1350,18 +1350,9 @@ class ProductManager:
|
||||
headers.append('价格')
|
||||
|
||||
rows = []
|
||||
html = ['<table style="border-collapse:collapse;width:100%;'
|
||||
'font-size:11px;line-height:1.5;">']
|
||||
# 主题感知(2026-09-18 暗色治理):内联样式可用 var(),跟 bricks.css 双主题变量
|
||||
th_style = ('padding:3px 6px;border:1px solid var(--line);background:var(--bg-side);'
|
||||
'color:var(--ink-3);font-weight:600;text-align:left;'
|
||||
'white-space:nowrap;')
|
||||
td_style = ('padding:3px 6px;border:1px solid var(--line);color:var(--ink-2);'
|
||||
'white-space:nowrap;')
|
||||
html.append('<tr>' + ''.join(
|
||||
'<th style="%s">%s</th>' % (th_style, _html_escape(str(h)))
|
||||
for h in headers) + '</tr>')
|
||||
|
||||
# 结构化返回(2026-09-18 用户纠正:价格表用 bricks 声明式控件渲染,
|
||||
# 后端不拼 HTML——Html 控件内联样式是暗色治理死角且违背声明式铁律)。
|
||||
# 单元格 = {'t': 文本, 'k': 'price'|'orig'|''},.ui 按 k 上色/划线。
|
||||
for p in prices:
|
||||
vals = []
|
||||
for key, _h in cols:
|
||||
@ -1373,23 +1364,13 @@ class ProductManager:
|
||||
else:
|
||||
v = (p.get('filter_labels') or {}).get(key[2:], '')
|
||||
vals.append(str(v if v is not None else ''))
|
||||
price_text = '¥%.4g %s' % (p['amount'], p.get('unit_label') or '元')
|
||||
cells = [{'t': v, 'k': ''} for v in vals]
|
||||
cells.append({'t': '¥%.4g %s' % (p['amount'], p.get('unit_label') or '元'),
|
||||
'k': 'price'})
|
||||
if discount < 1.0 - 1e-9:
|
||||
price_text += '(原价 ¥%.4g)' % p['original_price']
|
||||
rows.append(vals + [price_text])
|
||||
|
||||
price_html = ('<span style="color:#e74c3c;font-weight:600;">%s</span>'
|
||||
% _html_escape('¥%.4g %s' % (
|
||||
p['amount'], p.get('unit_label') or '元')))
|
||||
if discount < 1.0 - 1e-9:
|
||||
price_html += (' <span style="color:#94a3b8;text-decoration:'
|
||||
'line-through;">¥%.4g</span>' % p['original_price'])
|
||||
html.append('<tr>' + ''.join(
|
||||
'<td style="%s">%s</td>' % (td_style, _html_escape(v))
|
||||
for v in vals)
|
||||
+ '<td style="%s">%s</td></tr>' % (td_style, price_html))
|
||||
html.append('</table>')
|
||||
return {'headers': headers, 'rows': rows, 'html': ''.join(html)}
|
||||
cells.append({'t': '¥%.4g' % p['original_price'], 'k': 'orig'})
|
||||
rows.append(cells)
|
||||
return {'headers': headers, 'rows': rows}
|
||||
|
||||
async def get_customer_price_display(self, product_id=None, product_code=None,
|
||||
user_org_id=None):
|
||||
@ -1410,7 +1391,7 @@ class ProductManager:
|
||||
{'success', 'prices': [{'label','unit_price','unit_label','amount','unit',
|
||||
'filter_labels','original_price'}],
|
||||
'pricing_text', 'discount', 'original_text',
|
||||
'price_table': {'headers','rows','html'} 或 None(多价目时给出)}
|
||||
'price_table': {'headers': [...], 'rows': [[{'t','k'}...]]} 或 None(多价目时给出)}
|
||||
"""
|
||||
iface, product, err = await self._get_product_interface(
|
||||
product_id, product_code)
|
||||
|
||||
@ -162,12 +162,33 @@
|
||||
},
|
||||
{% else %}
|
||||
{% if price_table %}
|
||||
{# 多价目:表格展示(要素列+价格列),产线包月/包年、模型分辨率×类型分档都走这里 #}
|
||||
{# 多价目:声明式表格(2026-09-18 用户纠正:不用 Html 拼 table,用 bricks 控件;
|
||||
行类 tabular-header-row/tabular-row 框架双主题齐备;数据走 otext+i18n 回退原文) #}
|
||||
{
|
||||
"widgettype": "Html",
|
||||
"options": {
|
||||
"html": {{json.dumps(price_table.html, ensure_ascii=False)}}
|
||||
}
|
||||
"widgettype": "VBox",
|
||||
"options": {"width": "100%", "gap": "0"},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {"css": "tabular-header-row", "width": "100%"},
|
||||
"subwidgets": [
|
||||
{% for h in price_table.headers %}
|
||||
{"widgettype": "Text", "options": {"otext": {{json.dumps(h, ensure_ascii=False)}}, "text": {{json.dumps(h, ensure_ascii=False)}}, "i18n": true, "halign": "left", "css": "filler", "cfontsize": 0.75}}{{ "," if not loop.last }}
|
||||
{% endfor %}
|
||||
]
|
||||
}{{ "," if price_table.rows }}
|
||||
{% for row in price_table.rows %}
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {"css": "tabular-row", "width": "100%"},
|
||||
"subwidgets": [
|
||||
{% for c in row %}
|
||||
{"widgettype": "Text", "options": {"otext": {{json.dumps(c.t, ensure_ascii=False)}}, "text": {{json.dumps(c.t, ensure_ascii=False)}}, "i18n": true, "halign": "left", "css": "filler", "cfontsize": 0.75{% if c.k == 'price' %}, "color": "#e74c3c"{% elif c.k == 'orig' %}, "color": "var(--ink-3)", "textDecoration": "line-through"{% else %}, "color": "var(--ink-2)"{% endif %}}}{{ "," if not loop.last }}
|
||||
{% endfor %}
|
||||
]
|
||||
}{{ "," if not loop.last }}
|
||||
{% endfor %}
|
||||
]
|
||||
},
|
||||
{% else %}
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user