You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
5.3 KiB

2 days ago
  1. # -*- coding: utf-8 -*-
  2. import re
  3. import os
  4. from collections import defaultdict
  5. ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  6. proc_calls = re.compile(r'(?:getProcedureData|execProduceData)\("([^"]+)"')
  7. java_throw_rt = re.compile(r'throw new RuntimeException\("([^"]+)"')
  8. java_throw_cr = re.compile(r'throw new CustomerRuntimeException\(\d+,\s*"([^"]+)"')
  9. java_put_msg = re.compile(r'put\("(?:errorMsg|resultMsg|message|msg)"\s*,\s*"([^"]+)"')
  10. menus = []
  11. labels_print = []
  12. frontend = defaultdict(set)
  13. backend_msgs = defaultdict(set)
  14. proc_list = set()
  15. proc_handlers = set()
  16. # master.ftl
  17. master_path = os.path.join(ROOT, 'src/main/resources/templates/master.ftl')
  18. with open(master_path, encoding='utf-8') as f:
  19. content = f.read()
  20. for m in re.finditer(r'<a[^>]*>([^<]+)</a>', content):
  21. text = m.group(1).strip()
  22. if text:
  23. menus.append(text)
  24. for m in re.finditer(r'label="([^"]+)"', content):
  25. frontend['表单标签'].add(f'master.ftl: {m.group(1)}')
  26. for m in re.finditer(r"dialog\('setTitle',\s*'([^']+)'", content):
  27. frontend['弹窗标题'].add(m.group(1))
  28. for m in re.finditer(r"layer\.alert\('([^']+)'", content):
  29. frontend['layer提示'].add(m.group(1))
  30. for m in re.finditer(r"messager\.alert\('[^']*','([^']+)'", content):
  31. frontend['messager提示'].add(m.group(1))
  32. for m in re.finditer(r"messager\.confirm\('[^']*','([^']+)'", content):
  33. frontend['确认框'].add(m.group(1))
  34. # Java
  35. for dirpath, _, files in os.walk(os.path.join(ROOT, 'src/main/java')):
  36. for fn in files:
  37. if not fn.endswith('.java'):
  38. continue
  39. path = os.path.join(dirpath, fn)
  40. rel = os.path.relpath(path, ROOT).replace('\\', '/')
  41. with open(path, encoding='utf-8', errors='ignore') as f:
  42. text = f.read()
  43. for m in proc_calls.finditer(text):
  44. proc_list.add(m.group(1))
  45. if 'result_msg' in text or 'result_code' in text:
  46. proc_handlers.add(rel)
  47. for m in java_throw_rt.finditer(text):
  48. backend_msgs[m.group(1)].add(rel)
  49. for m in java_throw_cr.finditer(text):
  50. backend_msgs[m.group(1)].add(rel)
  51. for m in java_put_msg.finditer(text):
  52. backend_msgs[m.group(1)].add(rel)
  53. # Templates
  54. for dirpath, _, files in os.walk(os.path.join(ROOT, 'src/main/resources/templates')):
  55. for fn in files:
  56. if not fn.endswith('.ftl'):
  57. continue
  58. path = os.path.join(dirpath, fn)
  59. rel = os.path.relpath(path, ROOT).replace('\\', '/')
  60. with open(path, encoding='utf-8', errors='ignore') as f:
  61. text = f.read()
  62. if '/print/' in rel.replace('\\', '/'):
  63. for m in re.finditer(r'ADD_PRINT_TEXT\([^,]+,[^,]+,[^,]+,[^,]+,"([^"]+)"', text):
  64. s = m.group(1)
  65. if '${' not in s and not s.startswith('+'):
  66. labels_print.append((rel, s))
  67. for m in re.finditer(r'"([\u4e00-\u9fff]+)"', text):
  68. labels_print.append((rel, m.group(1)))
  69. for m in re.finditer(r'field:[^>]+>([^<]+)</th>', text):
  70. col = m.group(1).strip()
  71. if col:
  72. frontend['表格列名'].add(f'{rel}: {col}')
  73. for m in re.finditer(r'label="([^"]*)"', text):
  74. if re.search(r'[\u4e00-\u9fff]', m.group(1)):
  75. frontend['表单标签'].add(f'{rel}: {m.group(1)}')
  76. for m in re.finditer(r"title:\s*'([^']+)'", text):
  77. if re.search(r'[\u4e00-\u9fff]', m.group(1)) or m.group(1) in ('提示', 'Error', 'Confirm', 'Info'):
  78. frontend['弹窗标题'].add(f'{rel}: {m.group(1)}')
  79. for m in re.finditer(r"layer\.(?:alert|msg)\('([^']+)'", text):
  80. frontend['layer提示'].add(f'{rel}: {m.group(1)}')
  81. for m in re.finditer(r"messager\.(?:alert|confirm)\('[^']*',\s*'([^']+)'", text):
  82. frontend['messager提示'].add(f'{rel}: {m.group(1)}')
  83. for m in re.finditer(r'<h[1-4][^>]*>([^<]+)</h[1-4]>', text):
  84. t = m.group(1).strip()
  85. if re.search(r'[\u4e00-\u9fff]', t):
  86. frontend['页面标题'].add(f'{rel}: {t}')
  87. for m in re.finditer(r'<button[^>]*>([^<]+)</button>', text):
  88. t = m.group(1).strip()
  89. if re.search(r'[\u4e00-\u9fff]', t):
  90. frontend['按钮'].add(f'{rel}: {t}')
  91. # Output summary
  92. out = []
  93. out.append(f'Menus: {len(menus)}')
  94. out.append(f'Procedures: {len(proc_list)}')
  95. out.append(f'Backend messages: {len(backend_msgs)}')
  96. out.append(f'Print labels: {len(labels_print)}')
  97. for k, v in sorted(frontend.items()):
  98. out.append(f'Frontend {k}: {len(v)}')
  99. print('\n'.join(out))
  100. print('\n=== PROCEDURES ===')
  101. for p in sorted(proc_list):
  102. print(p)
  103. print('\n=== PROC HANDLERS ===')
  104. for p in sorted(proc_handlers):
  105. print(p)
  106. # Write JSON for doc generation
  107. import json
  108. data = {
  109. 'menus': menus,
  110. 'procedures': sorted(proc_list),
  111. 'procedure_handlers': sorted(proc_handlers),
  112. 'backend_messages': {k: sorted(v) for k, v in sorted(backend_msgs.items())},
  113. 'frontend': {k: sorted(v) for k, v in sorted(frontend.items())},
  114. 'print_labels': labels_print,
  115. }
  116. with open(os.path.join(ROOT, 'scripts', 'i18n_extract.json'), 'w', encoding='utf-8') as f:
  117. json.dump(data, f, ensure_ascii=False, indent=2)
  118. print('\nWrote scripts/i18n_extract.json')