yg-team-cli 2.6.4 → 2.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -212,6 +212,12 @@ var init_utils = __esm({
212
212
  static async read(file) {
213
213
  return await fs.readFile(file, "utf-8");
214
214
  }
215
+ /**
216
+ * 同步读取文件内容
217
+ */
218
+ static readSync(file) {
219
+ return fs.readFileSync(file, "utf-8");
220
+ }
215
221
  /**
216
222
  * 写入文件内容(自动创建父目录)
217
223
  */
@@ -1772,27 +1778,164 @@ var ModuleManager = class {
1772
1778
  } else if (module.type === "remote") {
1773
1779
  await this.generateRemoteSpecPlaceholder(targetPath, module);
1774
1780
  addedFiles.push(path5.relative(projectPath, targetPath));
1781
+ } else {
1782
+ await this.generateLocalSpecPlaceholder(targetPath, module);
1783
+ addedFiles.push(path5.relative(projectPath, targetPath));
1775
1784
  }
1776
1785
  }
1777
- if (module.type === "local" && module.backendFragments) {
1786
+ if (module.backendFragments) {
1778
1787
  const backendJavaDir = path5.join(projectPath, "backend/src/main/java");
1779
- const commonBasePath = path5.join(backendJavaDir, "org/yungu/common");
1788
+ const useTemplates = await FileUtils.exists(path5.join(templatesDir, "modules"));
1780
1789
  for (const fragment of module.backendFragments) {
1790
+ let sourcePath = null;
1791
+ let targetPath;
1792
+ let content;
1793
+ if (useTemplates) {
1794
+ sourcePath = path5.join(templatesDir, "modules", fragment.source);
1795
+ if (await FileUtils.exists(sourcePath)) {
1796
+ content = await FileUtils.read(sourcePath);
1797
+ }
1798
+ }
1799
+ if (!content) {
1800
+ content = this.generatePlaceholderCode(module, fragment);
1801
+ }
1802
+ if (fragment.target.startsWith("common/")) {
1803
+ const relativePath = fragment.target.replace(/^common\//, "org/yungu/common/");
1804
+ targetPath = path5.join(backendJavaDir, relativePath);
1805
+ } else if (fragment.target.startsWith("config/")) {
1806
+ const mainModule = this.findMainModule(projectPath);
1807
+ if (mainModule) {
1808
+ const relativePath = fragment.target.replace(/^config\//, `${mainModule}/config/`);
1809
+ targetPath = path5.join(backendJavaDir, relativePath);
1810
+ } else {
1811
+ targetPath = path5.join(backendJavaDir, fragment.target);
1812
+ }
1813
+ } else {
1814
+ targetPath = path5.join(backendJavaDir, fragment.target);
1815
+ }
1816
+ await FileUtils.ensureDir(path5.dirname(targetPath));
1817
+ await FileUtils.write(targetPath, content);
1818
+ addedFiles.push(path5.relative(projectPath, targetPath));
1819
+ }
1820
+ }
1821
+ if (module.frontendFragments) {
1822
+ const frontendSrcDir = path5.join(projectPath, "frontend/src");
1823
+ for (const fragment of module.frontendFragments) {
1781
1824
  const sourcePath = path5.join(templatesDir, "modules", fragment.source);
1782
- const targetPath = path5.join(commonBasePath, fragment.target);
1825
+ const targetPath = path5.join(frontendSrcDir, fragment.target);
1783
1826
  if (await FileUtils.exists(sourcePath)) {
1784
- await FileUtils.ensureDir(path5.dirname(targetPath));
1785
- let content = await FileUtils.read(sourcePath);
1786
- const targetPackage = "org.yungu.common." + path5.dirname(fragment.target).replace(/\//g, ".");
1787
- content = content.replace(/^package\s+[^;]+;/m, `package ${targetPackage};`);
1788
- await FileUtils.write(targetPath, content);
1827
+ await FileUtils.copy(sourcePath, targetPath);
1789
1828
  addedFiles.push(path5.relative(projectPath, targetPath));
1790
1829
  }
1791
1830
  }
1792
- } else if (module.type === "remote") {
1793
1831
  }
1794
1832
  return addedFiles;
1795
1833
  }
1834
+ /**
1835
+ * 查找主模块名 (第一个 service 类型的模块)
1836
+ */
1837
+ static findMainModule(projectPath) {
1838
+ const settingsPath = path5.join(projectPath, "backend/settings.gradle");
1839
+ const content = FileUtils.readSync(settingsPath);
1840
+ const matches = content.match(/include\s+'([^']+)'/g);
1841
+ if (matches) {
1842
+ for (const match of matches) {
1843
+ const moduleName = match.replace(/include\s+'/, "").replace(/'/, "");
1844
+ if (moduleName !== "common") {
1845
+ return moduleName;
1846
+ }
1847
+ }
1848
+ }
1849
+ return null;
1850
+ }
1851
+ /**
1852
+ * 生成占位符代码
1853
+ */
1854
+ static generatePlaceholderCode(module, fragment) {
1855
+ const targetPackage = path5.dirname(fragment.target).replace(/\//g, ".");
1856
+ const className = path5.basename(fragment.target, ".java");
1857
+ const moduleName = module.name;
1858
+ const moduleId = module.id;
1859
+ return `package ${targetPackage};
1860
+
1861
+ import lombok.extern.slf4j.Slf4j;
1862
+
1863
+ /**
1864
+ * ${moduleName} - \u5360\u4F4D\u7B26
1865
+ *
1866
+ * \u6B64\u6587\u4EF6\u7531 team-cli \u81EA\u52A8\u751F\u6210\u3002
1867
+ * \u6A21\u5757 ID: ${moduleId}
1868
+ *
1869
+ * \u4F7F\u7528\u8BF4\u660E:
1870
+ * 1. \u8BF7\u6839\u636E\u9879\u76EE\u5B9E\u9645\u9700\u6C42\u5B8C\u5584\u6B64\u6587\u4EF6
1871
+ * 2. \u6216\u53C2\u8003 docs/specs/${moduleId}/spec.md \u83B7\u53D6\u8BE6\u7EC6\u9700\u6C42
1872
+ */
1873
+ @Slf4j
1874
+ public class ${className} {
1875
+
1876
+ /**
1877
+ * TODO: \u5B9E\u73B0 ${moduleName} \u529F\u80FD
1878
+ */
1879
+ public void execute() {
1880
+ log.info("${className} - \u6267\u884C\u4E2D...");
1881
+ // \u5728\u6B64\u5B9E\u73B0\u5177\u4F53\u903B\u8F91
1882
+ }
1883
+ }
1884
+ `;
1885
+ }
1886
+ /**
1887
+ * 生成本地模块的 Spec 占位符
1888
+ */
1889
+ static async generateLocalSpecPlaceholder(targetPath, module) {
1890
+ const content = `# ${module.name}
1891
+
1892
+ ## \u529F\u80FD\u6982\u8FF0
1893
+ ${module.description}
1894
+
1895
+ ## \u4F7F\u7528\u8BF4\u660E
1896
+
1897
+ \u6B64\u6A21\u5757\u4E3A\u4E91\u8C37\u901A\u7528\u6A21\u5757\u7684\u5360\u4F4D\u7B26\u914D\u7F6E\u3002
1898
+
1899
+ ### \u914D\u7F6E\u6B65\u9AA4
1900
+
1901
+ 1. **\u6DFB\u52A0\u4F9D\u8D56**
1902
+
1903
+ \u5728 \`backend/build.gradle\` \u4E2D\u6DFB\u52A0:
1904
+
1905
+ \`\`\`groovy
1906
+ ${module.dependencies ? module.dependencies.map((d) => `implementation '${d}'`).join("\n") : ""}
1907
+ \`\`\`
1908
+
1909
+ 2. **\u914D\u7F6E\u6587\u4EF6**
1910
+
1911
+ \u6839\u636E\u9700\u6C42\u914D\u7F6E application.yml:
1912
+
1913
+ \`\`\`yaml
1914
+ # ${module.name} \u914D\u7F6E
1915
+ \`\`\`
1916
+
1917
+ 3. **\u5BFC\u5165\u914D\u7F6E\u7C7B**
1918
+
1919
+ \u5728\u4E3B Application \u7C7B\u4E0A\u6DFB\u52A0\u6CE8\u89E3:
1920
+
1921
+ \`\`\`java
1922
+ @SpringBootApplication
1923
+ @ComponentScan("${module.id}")
1924
+ public class Application {
1925
+ // ...
1926
+ }
1927
+ \`\`\`
1928
+
1929
+ 4. **\u53C2\u8003\u6587\u6863**
1930
+
1931
+ \u67E5\u770B docs/specs/${module.id}/spec.md \u83B7\u53D6\u8BE6\u7EC6\u5B9E\u73B0\u8BF4\u660E\u3002
1932
+
1933
+ ## \u4F9D\u8D56\u5173\u7CFB
1934
+
1935
+ ${module.requires ? `\u9700\u8981\u5148\u542F\u7528: ${module.requires.join(", ")}` : "\u65E0\u524D\u7F6E\u4F9D\u8D56"}
1936
+ `;
1937
+ await FileUtils.write(targetPath, content);
1938
+ }
1796
1939
  /**
1797
1940
  * 生成远程模块的 Spec 占位符
1798
1941
  */