index.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import { Events } from "queenjs";
  2. import { useCtx } from "../../ctx";
  3. import { Controller } from "../../core/controller";
  4. import { PackSource } from "../../objects/packSource";
  5. import { EditorCtrl } from "./editor";
  6. import {
  7. PackScene,
  8. PackGeom,
  9. PackProduct,
  10. PackSceneProduct,
  11. } from "@/comm/objects/pack";
  12. import { compMap } from "./tempComp";
  13. async function createDefaultSpu3dConf() {
  14. const currTime = new Date().toISOString();
  15. const source = new PackSource();
  16. source.state.scenes = [new PackScene()];
  17. // 初始化模型资产
  18. const geom = new PackGeom();
  19. geom.file = { url: "assets/box.fbx", size: 0 };
  20. const product = new PackProduct();
  21. product.geomId = geom.id;
  22. const sceneProd = new PackSceneProduct();
  23. sceneProd.state.prodId = product.id;
  24. const currScene = source.scenes[0];
  25. // currScene.envId = env.id;
  26. source.geoms.push(geom);
  27. source.products.push(product);
  28. // source.env3ds.push(env);
  29. currScene.products.push(sceneProd);
  30. const defaultData = {
  31. name: "",
  32. source: source.toJson(),
  33. createTime: currTime,
  34. updateTime: currTime,
  35. };
  36. return defaultData;
  37. }
  38. export class ProjectController extends Controller {
  39. RootDir = "";
  40. DataDir = "";
  41. HostURL = "";
  42. _swiftLocal = true;
  43. _editor?: EditorCtrl;
  44. _spu3dFile: any;
  45. get editor() {
  46. return this._editor as EditorCtrl;
  47. }
  48. async onReady() {
  49. const params = new URLSearchParams(location.search);
  50. const projectPath = params.get("path") as string;
  51. this.RootDir = projectPath;
  52. const deviceCtrl = useCtx().deviceCtrl;
  53. deviceCtrl.GetAppDataDir().then((dir: any) => {
  54. this.DataDir = dir;
  55. });
  56. if (!projectPath) {
  57. deviceCtrl.SetMainTitle("spu3d");
  58. return;
  59. }
  60. deviceCtrl.SetMainTitle("项目:" + projectPath);
  61. this.HostURL = await deviceCtrl.StartHttpServer(this.RootDir);
  62. console.log("host url=>", this.HostURL);
  63. await this.loadProject();
  64. }
  65. async save() {
  66. const detail = this._spu3dFile;
  67. detail.source = this.editor.pack.toJson();
  68. detail.updateTime = new Date().toISOString();
  69. const deviceCtrl = useCtx().deviceCtrl;
  70. const ok = await deviceCtrl.WriteFileText(
  71. `${this.RootDir}/project.spu3d`,
  72. JSON.stringify(detail)
  73. );
  74. if (!ok) {
  75. return Promise.reject("保存项目失败");
  76. }
  77. }
  78. async loadProject() {
  79. const deviceCtrl = useCtx().deviceCtrl;
  80. try {
  81. const { text } = await deviceCtrl.ReadFileText(
  82. `${this.RootDir}/project.spu3d`
  83. );
  84. const project = JSON.parse(text);
  85. this._spu3dFile = project;
  86. const pack = new PackSource();
  87. pack.fromJson(project.source);
  88. console.log("=================>", pack);
  89. this._editor = new EditorCtrl(pack);
  90. } catch (error) {
  91. alert("项目加载失败" + error);
  92. }
  93. }
  94. async loadQueen5() {
  95. const deviceCtrl = useCtx().deviceCtrl;
  96. try {
  97. const { text } = await deviceCtrl.ReadFileText(
  98. `${this.RootDir}/project.queen5`
  99. );
  100. let data = {} as any;
  101. if (!text) {
  102. data = { categories: ["64e4281a12c676099617ffc6"], title: "pc" };
  103. } else {
  104. data = JSON.parse(text);
  105. }
  106. return data;
  107. } catch (error) {
  108. alert("项目加载失败" + error);
  109. }
  110. }
  111. async getProjectDetail(
  112. dir: string
  113. ): ReturnType<typeof createDefaultSpu3dConf> {
  114. const deviceCtrl = useCtx().deviceCtrl;
  115. const ret = await deviceCtrl.ReadFileText(`${dir}/project.spu3d`);
  116. if (ret.text) {
  117. const info = JSON.parse(ret.text);
  118. return info;
  119. } else {
  120. //项目可能已经删除或数据错误了
  121. return Promise.reject("获取项目详情失败");
  122. }
  123. }
  124. getOutputDir() {
  125. return this.RootDir + "/" + "outputs";
  126. }
  127. getAppDataDir() {
  128. return this.DataDir;
  129. }
  130. getDefaultLogo() {
  131. return this.DataDir + "/static/thumbnail.png";
  132. }
  133. createPath(fpath: string) {
  134. return this.RootDir + "/" + fpath;
  135. }
  136. getSwiftUri(assetPath: string) {
  137. if (this._swiftLocal) return this.getLocalAbsoluteUri(assetPath);
  138. return this.getHttpAbsoluteUri(assetPath);
  139. }
  140. getHttpAbsoluteUri(url: string) {
  141. if (url.substring(0, 2) == "//") return "http://" + url;
  142. if (url.substring(0, 4) == "http") return url;
  143. if (url.charAt(0) == "/") return this.HostURL + url.substring(1);
  144. return this.HostURL + url;
  145. }
  146. getLocalAbsoluteUri(url: string) {
  147. if (url.substring(0, 2) == "//") return "http://" + url;
  148. if (url.substring(0, 4) == "http") return url;
  149. if (url.charAt(0) == "/") return this.RootDir + url;
  150. return this.RootDir + "/" + url;
  151. }
  152. getRelativeUri(url: string) {
  153. let s = this.HostURL.length;
  154. let pre = url.substring(0, s);
  155. if (pre == this.HostURL) return url.substring(s + 1);
  156. s = this.RootDir.length;
  157. pre = url.substring(0, s);
  158. if (pre == this.RootDir) return url.substring(s + 1);
  159. return "";
  160. }
  161. async createProject(path: string) {
  162. const deviceCtrl = useCtx().deviceCtrl;
  163. const filePath = `${path}/project.spu3d`;
  164. const isFileExit = await deviceCtrl.IsFileExit(filePath);
  165. if (isFileExit) {
  166. return Promise.reject("该项目已存在");
  167. }
  168. const name = path.split("/").pop() || "";
  169. const defSpu3dConf = await createDefaultSpu3dConf();
  170. defSpu3dConf.name = name;
  171. const appDir = await deviceCtrl.GetAppDataDir();
  172. await deviceCtrl.CopyFile(
  173. `${appDir}/static/default.png`,
  174. `${path}/assets/thumbnail.png`
  175. );
  176. await deviceCtrl.CopyFile(
  177. `${appDir}/static/box.fbx`,
  178. `${path}/assets/box.fbx`
  179. );
  180. await deviceCtrl.WriteFileText(filePath, JSON.stringify(defSpu3dConf));
  181. return filePath;
  182. }
  183. async pickProject() {
  184. const deviceCtrl = useCtx().deviceCtrl;
  185. const projectDir = await deviceCtrl.SelectDir();
  186. if (await this.isProjectExit(projectDir)) {
  187. return projectDir;
  188. } else {
  189. return Promise.reject();
  190. }
  191. }
  192. async isProjectExit(dir: string) {
  193. const deviceCtrl = useCtx().deviceCtrl;
  194. return await deviceCtrl.IsFileExit(`${dir}/project.spu3d`);
  195. }
  196. async saveProjectSource() {
  197. const detail = await this.getProjectDetail(this.RootDir);
  198. detail.source = this.editor.pack.toJson();
  199. detail.updateTime = new Date().toISOString();
  200. const deviceCtrl = useCtx().deviceCtrl;
  201. const ok = await deviceCtrl.WriteFileText(
  202. `${this.RootDir}/project.spu3d`,
  203. JSON.stringify(detail)
  204. );
  205. if (!ok) {
  206. return Promise.reject("保存项目失败");
  207. }
  208. }
  209. }