From 5162e3d5dd034487911514748e5b9a5b49976736 Mon Sep 17 00:00:00 2001 From: ChenX Date: Wed, 15 Aug 2018 09:38:23 +0800 Subject: [PATCH] =?UTF-8?q?!98=20=E9=87=8D=E6=9E=84=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F.=20Merge=20pull=20request=20!98=20from=20Che?= =?UTF-8?q?nX/fileServer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 3 +- package-lock.json | 22 +-- package.json | 2 +- src/Add-on/Save.ts | 41 ++--- src/ApplicationServices/Application.ts | 4 +- src/DatabaseServices/FileServer.ts | 155 +++++++++++++++++ src/Editor/MouseControls.ts | 1 - src/GraphicsSystem/Viewer.ts | 11 +- src/IndexedDb/IndexedDbStore.ts | 32 +++- src/UI/Components/Panel.tsx | 19 ++- src/UI/Components/SourceManage/FileItem.tsx | 12 +- src/UI/Components/SourceManage/FilePanel.tsx | 161 +++++------------- src/UI/Components/SourceManage/SoucePanel.tsx | 53 ++---- src/UI/Layout/ApplicationLayout.tsx | 7 +- src/UI/Store/DownPanelStore.ts | 10 +- src/UI/Store/FilePanelStore.ts | 19 --- src/UI/Store/TopPanelStore.ts | 42 +++++ 17 files changed, 340 insertions(+), 254 deletions(-) create mode 100644 src/DatabaseServices/FileServer.ts delete mode 100644 src/UI/Store/FilePanelStore.ts create mode 100644 src/UI/Store/TopPanelStore.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index 8509c10c3..cc58e7e4d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,7 @@ { "version": "0.2.0", - "configurations": [{ + "configurations": [ + { "type": "chrome", "request": "launch", "name": "Launch Chrome against localhost", diff --git a/package-lock.json b/package-lock.json index 023f36e3e..fd5967424 100644 --- a/package-lock.json +++ b/package-lock.json @@ -362,7 +362,7 @@ }, "@types/webvr-api": { "version": "0.0.34", - "resolved": "http://r.cnpmjs.org/@types/webvr-api/download/@types/webvr-api-0.0.34.tgz", + "resolved": "http://registry.npm.taobao.org/@types/webvr-api/download/@types/webvr-api-0.0.34.tgz", "integrity": "sha1-j6SQKN6SXHuLzj1VnTN0ziyJ7ig=", "dev": true }, @@ -810,7 +810,7 @@ }, "anymatch": { "version": "1.3.2", - "resolved": "http://r.cnpmjs.org/anymatch/download/anymatch-1.3.2.tgz", + "resolved": "http://registry.npm.taobao.org/anymatch/download/anymatch-1.3.2.tgz", "integrity": "sha1-VT3Lj5HjyImEXf26NMd3IbkLnXo=", "dev": true, "requires": { @@ -820,7 +820,7 @@ "dependencies": { "arr-diff": { "version": "2.0.0", - "resolved": "http://r.cnpmjs.org/arr-diff/download/arr-diff-2.0.0.tgz", + "resolved": "http://registry.npm.taobao.org/arr-diff/download/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { @@ -829,13 +829,13 @@ }, "array-unique": { "version": "0.2.1", - "resolved": "http://r.cnpmjs.org/array-unique/download/array-unique-0.2.1.tgz", + "resolved": "http://registry.npm.taobao.org/array-unique/download/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, "braces": { "version": "1.8.5", - "resolved": "http://r.cnpmjs.org/braces/download/braces-1.8.5.tgz", + "resolved": "http://registry.npm.taobao.org/braces/download/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { @@ -846,7 +846,7 @@ }, "expand-brackets": { "version": "0.1.5", - "resolved": "http://r.cnpmjs.org/expand-brackets/download/expand-brackets-0.1.5.tgz", + "resolved": "http://registry.npm.taobao.org/expand-brackets/download/expand-brackets-0.1.5.tgz", "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { @@ -855,13 +855,13 @@ }, "is-extglob": { "version": "1.0.0", - "resolved": "http://r.cnpmjs.org/is-extglob/download/is-extglob-1.0.0.tgz", + "resolved": "http://registry.npm.taobao.org/is-extglob/download/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "kind-of": { "version": "3.2.2", - "resolved": "http://r.cnpmjs.org/kind-of/download/kind-of-3.2.2.tgz", + "resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -870,7 +870,7 @@ }, "micromatch": { "version": "2.3.11", - "resolved": "http://r.cnpmjs.org/micromatch/download/micromatch-2.3.11.tgz", + "resolved": "http://registry.npm.taobao.org/micromatch/download/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { @@ -1872,7 +1872,7 @@ }, "chokidar": { "version": "1.7.0", - "resolved": "http://r.cnpmjs.org/chokidar/download/chokidar-1.7.0.tgz", + "resolved": "http://registry.npm.taobao.org/chokidar/download/chokidar-1.7.0.tgz", "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { @@ -7221,7 +7221,7 @@ }, "jsonfile": { "version": "4.0.0", - "resolved": "http://r.cnpmjs.org/jsonfile/download/jsonfile-4.0.0.tgz", + "resolved": "http://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { diff --git a/package.json b/package.json index 196122b35..7db439237 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "typescript": "^3.0.1", "url-loader": "^1.0.1", "wallaby-webpack": "^3.9.10", - "webpack": "^4.16.5", + "webpack": "^4.16.4", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.1.5", "webpack-merge": "^4.1.4" diff --git a/src/Add-on/Save.ts b/src/Add-on/Save.ts index a6bf5d2fd..c99aadbe9 100644 --- a/src/Add-on/Save.ts +++ b/src/Add-on/Save.ts @@ -1,47 +1,36 @@ import { app } from '../ApplicationServices/Application'; +import { Singleton } from '../Common/Singleton'; import { formateDate } from '../Common/Utils'; +import { FileInfo, FileServer } from '../DatabaseServices/FileServer'; import { Command } from '../Editor/CommandMachine'; -import { IndexedDbStore, StoreName } from '../IndexedDb/IndexedDbStore'; -import { FileInfo } from '../UI/Components/SourceManage/FilePanel'; -import { fileStore } from '../UI/Store/FilePanelStore'; export class Save implements Command { async exec() { - let cadFile = app.FileOut(); - - let store = await IndexedDbStore.CADStore(); - let fileId = store.m_CurrentFileId; - + //生成预览图 app.m_Viewer.onSize(120, 120); app.m_Viewer.Render(); let url = app.m_Viewer.m_Render.domElement.toDataURL("image/jpeg"); app.m_Viewer.onSize(); app.m_Viewer.Render(); + let fileServer = Singleton.GetInstance(FileServer); + let fileInfo: FileInfo; - if (!fileId) - { - let count = await store.Get(StoreName.FileId, "fileCount") as number || 0; - fileId = "f" + count; - store.Put(StoreName.FileId, "fileCount", ++count); - fileInfo = { - fileId, - title: `新文件${count}`, - modifyTime: "" - } - } - else - fileInfo = await store.Get(StoreName.Data, fileId) as FileInfo; + if (fileServer.m_CurFileId) + fileInfo = await fileServer.ReadFileInfo(fileServer.m_CurFileId); + if (!fileInfo) + fileInfo = await fileServer.CreateFile(); + //更新最后修改时间 fileInfo.modifyTime = formateDate(new Date(), "yyyy-MM-dd hh:mm:ss"); fileInfo.pic = url; - //储存文件数据和对应图纸 - store.Put(StoreName.Data, fileId, fileInfo); - store.Put(StoreName.Dwg, fileId, cadFile.Data); - store.m_CurrentFileId = fileId; - fileStore.SetCurFileId(fileId); + fileServer.UpdateFileInfo(fileInfo); + fileServer.UpdateFile(fileInfo.fileId, app.FileOut().Data); + + fileServer.m_CurFileId = fileInfo.fileId; + fileServer.SetLastOpenId(fileInfo.fileId); } } diff --git a/src/ApplicationServices/Application.ts b/src/ApplicationServices/Application.ts index 40e87077f..0041b74d2 100644 --- a/src/ApplicationServices/Application.ts +++ b/src/ApplicationServices/Application.ts @@ -142,6 +142,8 @@ export class ApplicationService { f.Reset(); this.m_Database.FileRead(f); - this.m_Viewer.m_CameraCtrl.ReadFile(new CADFile(f.Read())); + let viewData = f.Read(); + if (viewData) + this.m_Viewer.m_CameraCtrl.ReadFile(new CADFile(viewData)); } } diff --git a/src/DatabaseServices/FileServer.ts b/src/DatabaseServices/FileServer.ts new file mode 100644 index 000000000..3d710e373 --- /dev/null +++ b/src/DatabaseServices/FileServer.ts @@ -0,0 +1,155 @@ +import { IndexedDbStore, StoreName } from "../IndexedDb/IndexedDbStore"; +import { formateDate } from "../Common/Utils"; + +/** + * Store.Data 保存了FileInfo + * Store.Dwg 保存了文件的数据 + * Store.fileId 保存了文件的个数 + */ + + +export interface FileData +{ + key: string; + data: FileInfo; +} + +export interface FileInfo +{ + fileId: string; + title: string; + pic?: string; + position?: string; + picCount?: number; + modifyTime: string; +} + + +/** + * File server + * 保存CAD的文件服务,统一由这里经过文件的CRUD操作 + */ +export class FileServer +{ + constructor() + { + this.GetLastOpenId(); + } + + //** CRUD Start */ + + //创建新的文件C + async CreateFile(): Promise + { + let store = await IndexedDbStore.CADStore(); + let fId = await store.Get(StoreName.FileId, "fileCount") as number || 1; + let fileInfo: FileInfo = { + fileId: `f${fId}`, + title: `新文件${fId}`, + modifyTime: formateDate(new Date(), "yyyy-MM-dd hh:mm:ss"), + }; + + //保存这个文件描述 + store.Put(StoreName.Data, fileInfo.fileId, fileInfo); + //文件个数+1 + store.Put(StoreName.FileId, "fileCount", fId + 1); + + this.CreateFileEvent(fileInfo); + + return fileInfo; + } + //打开文件R + async ReadFile(fid: string) + { + let store = await IndexedDbStore.CADStore(); + return store.Get(StoreName.Dwg, fid); + } + + //保存文件U + async UpdateFile(fileId: string, data: any) + { + let store = await IndexedDbStore.CADStore(); + store.Put(StoreName.Dwg, fileId, data); + } + //删除文件D + async DeleteFile(fid: string) + { + let store = await IndexedDbStore.CADStore(); + store.Delete(StoreName.Data, fid); + store.Delete(StoreName.Dwg, fid); + this.DeleteFileEvent(fid); + } + + //** CRUP End */ + + //导出文件(下载) + DownloadFile() + { + + } + + //导入文件(上传) + ImportFile() + { + + } + + + + //读取文件列表 + async ReadFileList(): Promise + { + let store = await IndexedDbStore.CADStore(); + let fileList = await store.GetDataList(StoreName.Data) as FileData[];; + fileList.sort((f1, f2) => + { + if (f1.key.length !== f2.key.length) return f1.key.length - f2.key.length; + return f1.key.localeCompare(f2.key); + }); + return fileList.map(f => f.data); + } + + //读取文件的描述信息 + async ReadFileInfo(fid: string) + { + if (!fid) return undefined; + let store = await IndexedDbStore.CADStore(); + let fileInfo = await store.Get(StoreName.Data, fid) as FileInfo; + return fileInfo; + } + + //更新文件的描述信息 + async UpdateFileInfo(fileInfo: FileInfo) + { + let store = await IndexedDbStore.CADStore(); + await store.Put(StoreName.Data, fileInfo.fileId, fileInfo); + this.UpdateFileInfoEvent(fileInfo); + } + //**Event* + CreateFileEvent(f: FileInfo) + { + } + DeleteFileEvent(fid: string) + { + } + UpdateFileInfoEvent(fileInfo: FileInfo) + { + } + + //当前编辑的文件id + m_CurFileId: string; + //最后编辑的文件id + m_LastFileId: string; + async SetLastOpenId(id: string) + { + this.m_LastFileId = id; + let store = await IndexedDbStore.CADStore(); + store.Put(StoreName.FileId, "lastOpen", id); + } + async GetLastOpenId() + { + let store = await IndexedDbStore.CADStore(); + this.m_LastFileId = await store.Get(StoreName.FileId, "lastOpen"); + return this.m_LastFileId; + } +} diff --git a/src/Editor/MouseControls.ts b/src/Editor/MouseControls.ts index a3caaab62..a2616f450 100644 --- a/src/Editor/MouseControls.ts +++ b/src/Editor/MouseControls.ts @@ -45,7 +45,6 @@ export class MouseControls onDBMouseDown = (e) => { } - private raycaster: THREE.Raycaster = new THREE.Raycaster(); updateWordPoint = (e: MouseEvent) => { this.m_CurMousePointVCS.set(e.offsetX, e.offsetY, 0); diff --git a/src/GraphicsSystem/Viewer.ts b/src/GraphicsSystem/Viewer.ts index b84f83e89..534240930 100644 --- a/src/GraphicsSystem/Viewer.ts +++ b/src/GraphicsSystem/Viewer.ts @@ -4,6 +4,7 @@ import * as xaop from 'xaop'; import { end } from 'xaop'; import { Database } from '../DatabaseServices/Database'; import { Entity } from '../DatabaseServices/Entity'; +import { GenerateRaycaster } from '../Editor/PointPick'; import { cZeroVec, GetBox, GetBoxArr } from '../Geometry/GeUtils'; import { PlaneExt } from '../Geometry/Plane'; import { CameraUpdate } from './CameraUpdate'; @@ -168,15 +169,7 @@ export class Viewer { //变换和求交点 let plan = new PlaneExt(planVec || new THREE.Vector3(0, 0, 1)); - let raycaster = new THREE.Raycaster(); - // 射线从相机射线向屏幕点位置 - raycaster.setFromCamera( - { - x: (pt.x / this.Width) * 2 - 1, - y: - (pt.y / this.Height) * 2 + 1 - } - , this.m_CameraCtrl.Camera - ) + let raycaster = GenerateRaycaster(pt, this); plan.intersectRay(raycaster.ray, pt, true); } WorldToScreen(pt: Vector3): Vector3 diff --git a/src/IndexedDb/IndexedDbStore.ts b/src/IndexedDb/IndexedDbStore.ts index c3e0d4559..415304c36 100644 --- a/src/IndexedDb/IndexedDbStore.ts +++ b/src/IndexedDb/IndexedDbStore.ts @@ -10,8 +10,17 @@ enum DbMode export enum StoreName { Texture = "Texture", + /** + * 文件的数据 + */ Dwg = "Dwg", + /** + * 文件的FileInfo + */ Data = "Data", + /** + * 文件的个数 + */ FileId = "fileId", ConfigData = "configData" } @@ -36,10 +45,25 @@ export class IndexedDbStore await this.cadStore.Open(); return this.cadStore; } + + opening = false; + resFunctionList: Function[] = []; Open(): Promise { return new Promise((res) => { + if (this.db) + { + res(true); + return; + } + this.resFunctionList.push(res); + if (this.opening) + { + return; + } + this.opening = true; + let funcs = this.InitStore(); this.dbRequest = indexedDB.open("webCAD", funcs.length); @@ -47,17 +71,13 @@ export class IndexedDbStore this.dbRequest.onerror = () => { console.log("打开数据库出错!"); - res(false); + this.resFunctionList.forEach(res => res(false)); } //连接成功 this.dbRequest.onsuccess = (event) => { this.db = this.dbRequest.result; - this.db.onerror = () => - { - res(false); - } - res(true); + this.resFunctionList.forEach(res => res(true)); } //需要升级版本号时触发该事件 diff --git a/src/UI/Components/Panel.tsx b/src/UI/Components/Panel.tsx index 10a8831d1..999e4f097 100644 --- a/src/UI/Components/Panel.tsx +++ b/src/UI/Components/Panel.tsx @@ -2,6 +2,7 @@ import { Switch } from '@blueprintjs/core'; import { inject, observer } from 'mobx-react'; import * as React from 'react'; import { DownPanelStore } from '../Store/DownPanelStore'; +import { TopPanelStore } from '../Store/TopPanelStore'; import { SettingPanel } from './SettingPanel/SettingPanel'; import Login from './signComponent/login'; import SoucePanel from './SourceManage/SoucePanel'; @@ -12,11 +13,13 @@ interface TopPanelState isCollapse: boolean; panelType: string; } -//顶部标题栏. -//TODO:Ajax请求,获得登录状态 -export class TopPanel extends React.Component<{}, {}> + +//顶部标题栏. TODO:Ajax请求,获得登录状态 +@inject("store") +@observer +export class TopPanel extends React.Component<{ store?: TopPanelStore }, {}> { - state: TopPanelState + state: TopPanelState; constructor(props) { super(props); @@ -72,7 +75,7 @@ export class TopPanel extends React.Component<{}, {}>