dy-dashboard/fix_frozen_fields.py
2026-10-28 11:14:17 +08:00

115 lines
8.5 KiB
Python

#!/usr/bin/env python3
"""批量修改国内/海外订单管理页面:冻结列 + 字段设置 + 固定表头"""
import re
with open('static/js/app.js', 'r') as f:
js = f.read()
# =============================================
# DOMESTIC: 冻结5列的header + 固定表头 + 字段设置按钮
# =============================================
# 冻结列样式helper
FROZEN_HEADER = 'position:sticky;left:{0}px;top:0;z-index:11;background:var(--bg,#f5f5f5)'
FROZEN_CELL = 'position:sticky;left:{0}px;top:0;z-index:2;background:var(--card-bg,#fff)'
# Domestic header: 5 columns need frozen positioning
# Offsets: 列宽累计
# #(50)+日期(100)=150, +计划下单时间(140)=290, +新旧品(60)=350, +编码(120)=470, +名称(200)=670
dom_header_updates = [
('<th style="min-width:140px">计划下单时间</th>',
'<th style="min-width:140px;' + FROZEN_HEADER.format(150) + '">计划下单时间</th>'),
('<th style="min-width:60px">新旧品</th>',
'<th style="min-width:60px;' + FROZEN_HEADER.format(290) + '">新旧品</th>'),
('<th style="min-width:120px">编码</th>',
'<th style="min-width:120px;' + FROZEN_HEADER.format(350) + '">编码</th>'),
('<th style="min-width:200px">名称</th>',
'<th style="min-width:200px;' + FROZEN_HEADER.format(470) + '">名称</th>'),
]
for old, new in dom_header_updates:
if old in js:
js = js.replace(old, new, 1)
print(f"✅ 国内表头冻结: {old.split('>')[0].split('"')[1]}")
# Domestic data cells: 冻结5列的数据行
# The cells are rendered in domesticLoadOrders function
# 日期: already sticky
# 计划下单时间: <td>' + escHtml(r['计划下单时间'] || '') + '</td>
dom_cell_updates = [
("html += '<td>' + escHtml(r['计划下单时间'] || '') + '</td>';\n html += '<td>' + escHtml(r['新旧品'] || '') + '</td>';",
"html += '<td style=\"position:sticky;left:150px;z-index:2;background:var(--card-bg,#fff)\">' + escHtml(r['计划下单时间'] || '') + '</td>';\n html += '<td style=\"position:sticky;left:290px;z-index:2;background:var(--card-bg,#fff)\">' + escHtml(r['新旧品'] || '') + '</td>';"),
]
# For 编码 and 名称: they come after 新旧品
old_cells = "html += '<td style=\"position:sticky;left:290px;z-index:2;background:var(--card-bg,#fff)\">' + escHtml(r['新旧品'] || '') + '</td>';\n html += '<td><code>' + escHtml(r['编码'] || '') + '</code></td>';\n html += '<td style=\"max-width:250px;overflow:hidden;text-overflow:ellipsis\" title=\"' + escHtml(r['名称'] || '') + '\">' + escHtml(r['名称'] || '') + '</td>';"
new_cells = "html += '<td style=\"position:sticky;left:290px;z-index:2;background:var(--card-bg,#fff)\">' + escHtml(r['新旧品'] || '') + '</td>';\n html += '<td style=\"position:sticky;left:350px;z-index:2;background:var(--card-bg,#fff)\"><code>' + escHtml(r['编码'] || '') + '</code></td>';\n html += '<td style=\"position:sticky;left:470px;z-index:2;background:var(--card-bg,#fff);max-width:250px;overflow:hidden;text-overflow:ellipsis\" title=\"' + escHtml(r['名称'] || '') + '\">' + escHtml(r['名称'] || '') + '</td>';"
if old_cells in js:
js = js.replace(old_cells, new_cells, 1)
print("✅ 国内数据单元格: 编码+名称冻结")
else:
print("❌ 国内数据单元格: 未匹配")
# =============================================
# OVERSEAS: 冻结4列 (日期+计划下单时间+产品编码+货品名称)
# 海外没有 新旧品 列,只有 日期+计划下单时间+产品编码+货品名称
# =============================================
# Overseas header offsets: #(50)+日期(100)=150, +计划下单时间(140)=290, +产品编码(120)=410, +货品名称(200)=610
ov_header_updates = [
('<th style="min-width:140px">计划下单时间</th>',
'<th style="min-width:140px;' + FROZEN_HEADER.format(150) + '">计划下单时间</th>'),
('<th style="min-width:120px">产品编码</th>',
'<th style="min-width:120px;' + FROZEN_HEADER.format(290) + '">产品编码</th>'),
('<th style="min-width:200px">货品名称</th>',
'<th style="min-width:200px;' + FROZEN_HEADER.format(410) + '">货品名称</th>'),
]
for old, new in ov_header_updates:
if old in js:
js = js.replace(old, new, 1)
print(f"✅ 海外表头冻结: {old.split('>')[0].split('"')[1]}")
# Overseas data cells
ov_cells_1 = "html += '<td>' + escHtml(r['计划下单时间'] || '') + '</td>';\n html += '<td><code>' + escHtml(r['产品编码'] || '') + '</code></td>';"
ov_cells_1_new = "html += '<td style=\"position:sticky;left:150px;z-index:2;background:var(--card-bg,#fff)\">' + escHtml(r['计划下单时间'] || '') + '</td>';\n html += '<td style=\"position:sticky;left:290px;z-index:2;background:var(--card-bg,#fff)\"><code>' + escHtml(r['产品编码'] || '') + '</code></td>';"
if ov_cells_1 in js:
js = js.replace(ov_cells_1, ov_cells_1_new, 1)
print("✅ 海外数据单元格: 计划下单时间+产品编码冻结")
else:
print("❌ 海外数据单元格: 未匹配1")
# 货品名称 cell
ov_cells_2 = "html += '<td style=\"max-width:250px;overflow:hidden;text-overflow:ellipsis\" title=\"' + escHtml(r['货品名称'] || '') + '\">' + escHtml(r['货品名称'] || '') + '</td>';"
ov_cells_2_new = "html += '<td style=\"position:sticky;left:410px;z-index:2;background:var(--card-bg,#fff);max-width:250px;overflow:hidden;text-overflow:ellipsis\" title=\"' + escHtml(r['货品名称'] || '') + '\">' + escHtml(r['货品名称'] || '') + '</td>';"
if ov_cells_2 in js:
js = js.replace(ov_cells_2, ov_cells_2_new, 1)
print("✅ 海外数据单元格: 货品名称冻结")
else:
print("❌ 海外数据单元格: 未匹配2")
# =============================================
# 字段设置: 添加按钮和弹窗
# =============================================
# 在 domestic card-header 里添加字段设置按钮
# Current card header for domestic
dom_card_header = '<div class=\"card-header\" style=\"display:flex;justify-content:space-between;align-items:center\">\n <h3>📦 国内采购下单明细</h3>\n <div>\n <button class=\"btn btn-sm btn-primary\" onclick=\"domesticAddRow()\">+ 新增</button>\n <button class=\"btn btn-sm btn-outline\" onclick=\"domesticExport()\">导出</button>\n </div>\n </div>'
dom_card_new = '<div class=\"card-header\" style=\"display:flex;justify-content:space-between;align-items:center\">\n <h3>📦 国内采购下单明细</h3>\n <div>\n <button class=\"btn btn-sm btn-primary\" onclick=\"domesticAddRow()\">+ 新增</button>\n <button class=\"btn btn-sm btn-outline\" onclick=\"domesticExport()\">导出</button>\n <button class=\"btn btn-sm btn-outline\" onclick=\"openDomesticColModal()\">⚙ 字段设置</button>\n </div>\n </div>'
if dom_card_header in js:
js = js.replace(dom_card_header, dom_card_new, 1)
print("✅ 国内: 添加字段设置按钮")
else:
print("❌ 国内: 字段设置按钮未匹配")
# Overseas card header
ov_card_header = '<div class=\"card-header\" style=\"display:flex;justify-content:space-between;align-items:center\">\n <h3>🌍 海外采购下单明细</h3>\n <div>\n <button class=\"btn btn-sm btn-primary\" onclick=\"overseasAddRow()\">+ 新增</button>\n <button class=\"btn btn-sm btn-outline\" onclick=\"overseasExport()\">导出</button>\n </div>\n </div>'
ov_card_new = '<div class=\"card-header\" style=\"display:flex;justify-content:space-between;align-items:center\">\n <h3>🌍 海外采购下单明细</h3>\n <div>\n <button class=\"btn btn-sm btn-primary\" onclick=\"overseasAddRow()\">+ 新增</button>\n <button class=\"btn btn-sm btn-outline\" onclick=\"overseasExport()\">导出</button>\n <button class=\"btn btn-sm btn-outline\" onclick=\"openOverseasColModal()\">⚙ 字段设置</button>\n </div>\n </div>'
if ov_card_header in js:
js = js.replace(ov_card_header, ov_card_new, 1)
print("✅ 海外: 添加字段设置按钮")
else:
print("❌ 海外: 字段设置按钮未匹配")
print("\n✅ 写入文件中...")
with open('static/js/app.js', 'w') as f:
f.write(js)
print("✅ 保存完成")