migrate-quote-vue.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #!/usr/bin/env python3
  2. """Migrate CRM quote Vue files to shanxia2.0 portal conventions."""
  3. import re
  4. from pathlib import Path
  5. ROOT = Path(__file__).resolve().parents[1]
  6. TARGET_DIRS = [
  7. ROOT / "src/views/crm/quote",
  8. ROOT / "src/components",
  9. ]
  10. DICT_TYPES = [
  11. "crm_quote_status",
  12. "crm_product_unit",
  13. "crm_product_gg",
  14. "crm_customer_type",
  15. "crm_customer_level",
  16. "crm_industry",
  17. "crm_shfs",
  18. ]
  19. SCRIPT_IMPORTS = """import { useDictStore } from '@/store/modules/dict'
  20. import DictTag from '@/components/DictTag/index.vue'
  21. import ListPagination from '@/components/ListPagination/index.vue'
  22. import { $modal } from '@/utils/modal'
  23. """
  24. def migrate_file(path: Path) -> None:
  25. if path.suffix != ".vue":
  26. return
  27. text = path.read_text(encoding="utf-8")
  28. orig = text
  29. text = text.replace("@/utils/ruoyi", "@/utils/format")
  30. text = text.replace("CustomerDetail", "CustomerDetailDialog")
  31. text = text.replace(
  32. "@/views/crm/customer/detail.vue",
  33. "@/views/crm/customer/CustomerDetailDialog.vue",
  34. )
  35. text = text.replace("@/utils/request", "@/utils/http")
  36. text = text.replace("import { useDict } from '@/utils/dict';\n", "")
  37. text = text.replace("import { useDict } from '@/utils/dict'\n", "")
  38. for dt in DICT_TYPES:
  39. text = re.sub(
  40. rf'<dict-tag\s+:options="{dt}"\s+:value="([^"]+)"\s*/>',
  41. rf'<DictTag dict-type="{dt}" :value="\1" />',
  42. text,
  43. )
  44. text = re.sub(
  45. r"const \{ proxy \} = getCurrentInstance\(\)[^;]*;\s*\n\s*const \{ crm_[^}]+\} = toRefs<any>\(proxy[^)]+\);\s*\n",
  46. "",
  47. text,
  48. flags=re.MULTILINE,
  49. )
  50. text = re.sub(
  51. r"const \{ crm_[^}]+\} = toRefs<any>\(proxy[^)]+\);\s*\n",
  52. "",
  53. text,
  54. )
  55. text = text.replace(
  56. "import { listUser } from '@/api/system/user';",
  57. "import { fetchUserList } from '@/api/admin';",
  58. )
  59. text = text.replace(
  60. "import { listUser } from '@/api/system/user'",
  61. "import { fetchUserList } from '@/api/admin'",
  62. )
  63. text = text.replace(
  64. "import type { UserVO } from '@/api/system/user/types';",
  65. "",
  66. )
  67. text = re.sub(
  68. r"const res = await listUser\(\{([^}]+)\}\);\s*\n\s*userList\.value = res\.rows \|\| \[\];",
  69. r"""const res = await fetchUserList({ page: 1, pageSize: 50, keyword: undefined, status: '0' });
  70. userList.value = (res.list || []).map((u: any) => ({
  71. userId: u.id,
  72. nickName: u.nickName,
  73. userName: u.userNo,
  74. deptName: u.deptName
  75. }));""",
  76. text,
  77. flags=re.DOTALL,
  78. )
  79. text = text.replace("listCustomer", "fetchCustomerList")
  80. text = text.replace(
  81. "import { fetchCustomerList } from '@/api/crm/customer';",
  82. "import { fetchCustomerList } from '@/api/crm/customer';",
  83. )
  84. text = text.replace(
  85. "from '@/api/crm/customer/types'",
  86. "from '@/api/crm/customer'",
  87. )
  88. text = text.replace("listContact", "fetchContactList")
  89. text = text.replace(
  90. "import { fetchContactList } from '@/api/crm/customer';",
  91. "import { fetchContactList } from '@/api/contact';",
  92. )
  93. text = text.replace("listOpportunity", "listOpportunity")
  94. text = text.replace("<pagination", "<ListPagination")
  95. text = text.replace("</pagination>", "</ListPagination>")
  96. text = text.replace("proxy?.$modal.", "$modal.")
  97. text = text.replace("proxy.$modal.", "$modal.")
  98. text = text.replace("shareDialog.shareLink = res.data;", "shareDialog.shareLink = res as string;")
  99. if "DictTag" in text and "import DictTag" not in text:
  100. if "<script setup" in text:
  101. text = text.replace("<script setup", f"<script setup", 1)
  102. idx = text.find("<script setup")
  103. end = text.find("\n", idx)
  104. text = text[: end + 1] + SCRIPT_IMPORTS + text[end + 1 :]
  105. if path.name in ("CustomerSelector.vue", "ContactSelector.vue", "OpportunitySelector.vue", "TinyMceEditor/index.vue"):
  106. pass
  107. if text != orig:
  108. path.write_text(text, encoding="utf-8")
  109. print(f"updated: {path.relative_to(ROOT)}")
  110. def main():
  111. for d in TARGET_DIRS:
  112. if not d.exists():
  113. continue
  114. for path in d.rglob("*.vue"):
  115. if "ListPagination" in str(path) or "DictTag" in str(path):
  116. continue
  117. migrate_file(path)
  118. if __name__ == "__main__":
  119. main()