181 lines
6.0 KiB
Python
181 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
批量更新所有PC页面,应用统一的layout.js导航栏
|
||
"""
|
||
import os
|
||
import re
|
||
|
||
# 需要更新的文件和对应的activeKey
|
||
PAGES_CONFIG = {
|
||
# 项目相关
|
||
'project-approval.html': 'project',
|
||
'project-bidding.html': 'project',
|
||
'project-contract.html': 'project',
|
||
'approval-detail.html': 'approval',
|
||
'bidding-detail.html': 'project',
|
||
'contract-detail.html': 'project',
|
||
# 财务相关
|
||
'finance-payment.html': 'finance',
|
||
'finance-request.html': 'finance',
|
||
'invoice-detail.html': 'finance',
|
||
'request-detail.html': 'finance',
|
||
# 过程管理
|
||
'progress-query.html': 'process',
|
||
'start-detail.html': 'process',
|
||
'output-detail.html': 'process',
|
||
'output-submit.html': 'process',
|
||
# 报表相关
|
||
'report-project.html': 'report',
|
||
'report-project-detail.html': 'report',
|
||
'report-project-summary.html': 'report',
|
||
'report-output-detail.html': 'report',
|
||
'report-output-summary.html': 'report',
|
||
'report-payable-detail.html': 'report',
|
||
'report-payable-summary.html': 'report',
|
||
'report-receivable-detail.html': 'report',
|
||
'report-receivable-summary.html': 'report',
|
||
# 系统设置
|
||
'settings-org.html': 'settings',
|
||
'settings-role.html': 'settings',
|
||
'settings-user.html': 'settings',
|
||
'settings-dict.html': 'settings',
|
||
'settings-param.html': 'settings',
|
||
'settings-log.html': 'settings',
|
||
'settings-workflow.html': 'settings',
|
||
# 个人中心(注意:个人中心可能不需要顶部导航,或者使用特殊key)
|
||
'profile.html': 'home', # 个人中心可以算作home模块
|
||
'profile-edit.html': 'home',
|
||
'change-password.html': 'home',
|
||
}
|
||
|
||
# 导航栏CSS样式(需要删除的部分)
|
||
NAVBAR_CSS_PATTERN = re.compile(
|
||
r'\.navbar\s*\{[^}]+\}.*?\.navbar-right\s*\{[^}]+\}',
|
||
re.DOTALL
|
||
)
|
||
|
||
# 导航栏HTML(需要删除的部分)
|
||
NAVBAR_HTML_PATTERN = re.compile(
|
||
r'<div class="navbar">.*?</div>\s*</div>\s*<div class="main-container">',
|
||
re.DOTALL
|
||
)
|
||
|
||
# 简化的CSS删除模式(匹配常见的navbar样式)
|
||
NAVBAR_CSS_SIMPLE = re.compile(
|
||
r'\.navbar\s*\{.*?\n\s*\}\s*\n\s*\.navbar-left\s*\{.*?\n\s*\}\s*\n\s*\.logo\s*\{.*?\n\s*\}\s*\n\s*\.nav-menu\s*\{.*?\n\s*\}\s*\n\s*\.nav-item\s*\{.*?\n\s*\}\s*\n\s*(?:\.nav-item:hover\s*\{.*?\n\s*\}\s*\n\s*)?(?:\.nav-item\.active\s*\{.*?\n\s*\}\s*\n\s*)?\.navbar-right\s*\{.*?\n\s*\}\s*\n',
|
||
re.DOTALL
|
||
)
|
||
|
||
def remove_navbar_css(content):
|
||
"""移除导航栏相关的CSS"""
|
||
# 先尝试完整匹配
|
||
content = NAVBAR_CSS_SIMPLE.sub('', content)
|
||
# 如果还有残留,尝试更宽松的匹配
|
||
lines = content.split('\n')
|
||
result = []
|
||
skip = False
|
||
skip_count = 0
|
||
for i, line in enumerate(lines):
|
||
if '.navbar' in line or '.navbar-left' in line or '.logo' in line or '.nav-menu' in line or '.nav-item' in line or '.navbar-right' in line:
|
||
if '{' in line:
|
||
skip = True
|
||
skip_count = 0
|
||
continue
|
||
if skip:
|
||
if '{' in line:
|
||
skip_count += line.count('{')
|
||
if '}' in line:
|
||
skip_count -= line.count('}')
|
||
if skip_count <= 0:
|
||
skip = False
|
||
continue
|
||
if not skip:
|
||
result.append(line)
|
||
return '\n'.join(result)
|
||
|
||
def remove_navbar_html(content):
|
||
"""移除导航栏HTML"""
|
||
# 查找并删除navbar div
|
||
pattern = re.compile(
|
||
r'<div class="layout-container">\s*<div class="navbar">.*?</div>\s*</div>\s*<div class="main-container">',
|
||
re.DOTALL
|
||
)
|
||
content = pattern.sub('<div class="layout-container">\n <div class="main-container">', content)
|
||
return content
|
||
|
||
def add_layout_js(content, active_key):
|
||
"""添加layout.js引用和调用"""
|
||
# 查找</body>前的script标签
|
||
# 先检查是否已经有layout.js
|
||
if 'layout.js' in content:
|
||
# 如果已有,确保injectLayout调用正确
|
||
if f'injectLayout(\'{active_key}\')' not in content:
|
||
content = re.sub(
|
||
r'injectLayout\([^)]+\)',
|
||
f'injectLayout(\'{active_key}\')',
|
||
content
|
||
)
|
||
return content
|
||
|
||
# 查找最后一个</script>标签
|
||
script_pattern = re.compile(r'(</script>)(\s*</div>\s*</body>)', re.DOTALL)
|
||
if script_pattern.search(content):
|
||
content = script_pattern.sub(
|
||
r'\1\n <script src="layout.js"></script>\n <script>\n injectLayout(\'' + active_key + r'\');\n </script>\2',
|
||
content
|
||
)
|
||
else:
|
||
# 如果没有script,在</body>前添加
|
||
content = content.replace(
|
||
'</body>',
|
||
' <script src="layout.js"></script>\n <script>\n injectLayout(\'' + active_key + '\');\n </script>\n</body>'
|
||
)
|
||
|
||
return content
|
||
|
||
def update_file(filepath, active_key):
|
||
"""更新单个文件"""
|
||
if not os.path.exists(filepath):
|
||
print(f'文件不存在: {filepath}')
|
||
return False
|
||
|
||
with open(filepath, 'r', encoding='utf-8') as f:
|
||
content = f.read()
|
||
|
||
original_content = content
|
||
|
||
# 1. 移除navbar CSS(保留layout-container等必要样式)
|
||
# 只删除navbar相关的,保留其他
|
||
content = remove_navbar_css(content)
|
||
|
||
# 2. 移除navbar HTML
|
||
content = remove_navbar_html(content)
|
||
|
||
# 3. 添加layout.js引用和调用
|
||
content = add_layout_js(content, active_key)
|
||
|
||
if content != original_content:
|
||
with open(filepath, 'w', encoding='utf-8') as f:
|
||
f.write(content)
|
||
print(f'✓ 更新: {filepath} (activeKey: {active_key})')
|
||
return True
|
||
else:
|
||
print(f'- 无需更新: {filepath}')
|
||
return False
|
||
|
||
def main():
|
||
pc_dir = 'pc'
|
||
updated_count = 0
|
||
|
||
for filename, active_key in PAGES_CONFIG.items():
|
||
filepath = os.path.join(pc_dir, filename)
|
||
if update_file(filepath, active_key):
|
||
updated_count += 1
|
||
|
||
print(f'\n共更新 {updated_count} 个文件')
|
||
|
||
if __name__ == '__main__':
|
||
main()
|
||
|