!1975 功能:模板导入导出

pull/1977/MERGE
黄诗津 2 years ago committed by ChenX
parent 0cee6cdd2e
commit 09ad246455

@ -2,7 +2,7 @@ import { Intent } from "@blueprintjs/core";
import { HistoryToaster, OperLogs } from "../Add-on/File/OperLog";
import { app } from "../ApplicationServices/Application";
import { FileSystem } from "../Common/FileSystem";
import { FileUrls } from "../Common/HostUrl";
import { FileUrls, TemplateUrls } from "../Common/HostUrl";
import { inflateBase64 } from "../Common/inflate";
import { DirectoryId, PostJson, RequestStatus } from "../Common/Request";
import { deflate } from "../Common/SerializeMaterial";
@ -26,6 +26,7 @@ export interface IFileInfo
name?: string;
logo?: string;
file?: string;
props?: string;
zip_type?: "gzip";
update_date?: string;
code?: string;
@ -299,6 +300,25 @@ export class FileServer extends Singleton
if (file)
FileSystem.WriteFile(fileInfo.name + ".json", btoa(JSON.stringify({ file, id: store.shopId })));
}
async DownloadTemplate(fid: string)
{
let data = await PostJson(TemplateUrls.detail, { module_id: fid });
let templateInfo: IFileInfo;
if (data.err_code === RequestStatus.Ok && data.modules)
{
templateInfo = {
name: data.modules.name,
file: data.modules.file,
logo: data.modules.logo,
props: data.modules.props,
};
}
const store = TopPanelStore.GetInstance();
let { file, logo, props } = templateInfo;
if (file && logo && props)
FileSystem.WriteFile(templateInfo.name + ".json", btoa(JSON.stringify({ file, id: store.shopId, logo, props, type: "template" })));
}
private SaveCurrentFileInfo(fileInfo: IFileInfo)
{
if (fileInfo.name)

@ -1,20 +1,18 @@
import { Button, Intent, MenuItem, ProgressBar } from '@blueprintjs/core';
import { Button, Intent, MenuItem } from '@blueprintjs/core';
import { observable } from 'mobx';
import { inject, observer } from 'mobx-react';
import pako from 'pako';
import * as React from 'react';
import { app } from '../../../ApplicationServices/Application';
import { FileSystem } from '../../../Common/FileSystem';
import { CURRENT_HOST, FileUrls } from '../../../Common/HostUrl';
import { DirectoryId } from '../../../Common/Request';
import { StoreageKeys } from '../../../Common/StoreageKeys';
import { CADFiler } from '../../../DatabaseServices/CADFiler';
import { FileServer } from '../../../DatabaseServices/FileServer';
import { TopPanelStore } from '../../Store/TopPanelStore';
import { AppToaster } from '../Toaster';
import { CommonPanel, IDirectoryProps } from './CommonPanel';
import { FileList as CFileList } from './FileList';
import { HandleDirComponent } from './HandleDirComponent';
import { ImportFile } from './ImportFile';
export interface Props
{
@ -31,108 +29,6 @@ export class FilePanel extends React.Component<Props, {}>
commonPanel: CommonPanel;
private canCreateFile = observable.box(false);
private currentFileInfo = { fid: null, name: null };
selectEl: HTMLInputElement;
@observable private _isImporting = false;
handleImportFile = async (files: FileList) =>
{
let key = AppToaster.show({
message: <ProgressBar
className="docs-toast-progress"
intent={Intent.PRIMARY}
value={0 / files.length}
/>
});
this._isImporting = true;
const dir_id = this.commonPanel['currentDir'].id;
const shopId = TopPanelStore.GetInstance().shopId;
for (let i = 0, len = files.length; i < len; i++)
{
let f = files.item(i);
if (f.type === "application/json")
{
let dataStr = await FileSystem.ReadFileAsText(f);
if (!dataStr)
{
AppToaster.show({
message: f.name + "格式不正确",
timeout: 3000,
intent: Intent.DANGER
});
}
else
{
try
{
let { file, id } = JSON.parse(atob(dataStr));
if (!file || !id)
{
AppToaster.show({
message: f.name + "格式不正确",
timeout: 3000,
intent: Intent.DANGER
});
}
else if (shopId !== id && TopPanelStore.GetInstance().userName !== "cx")
{
AppToaster.show({
message: f.name + "不属于您的店铺,鉴权失败",
timeout: 3000,
intent: Intent.DANGER
});
}
else
{
let fserver = FileServer.GetInstance() as FileServer;
await fserver.UploadFile({
dir_id,
name: f.name.replace(".json", ""),
file: file
});
}
} catch (err)
{
AppToaster.show({
message: f.name + "格式不正确",
timeout: 3000,
intent: Intent.DANGER
});
}
}
}
else
{
try
{
let userName = localStorage.getItem(StoreageKeys.UserName);
if (userName === "cx")
{
let file = pako.inflate(new Uint8Array(await f.arrayBuffer()), { to: "string" });
app.OpenFile(new CADFiler(JSON.parse(file)));
}
return;
}
catch (error)
{
}
}
AppToaster.show({
message: <ProgressBar
stripes={i < len - 1}
className="docs-toast-progress"
intent={i === len - 1 ? Intent.SUCCESS : Intent.PRIMARY}
value={(i + 1) / files.length}
/>,
timeout: i === len - 1 ? 500 : 0
}, key);
}
await this.commonPanel.handleGetData();
this._isImporting = false;
this.selectEl.value = "";
};
handleAddNewFile = (name: string, currentDir: IDirectoryProps) =>
{
if (!app.Saved && !confirm("您当前图纸还未保存,是否放弃保存?"))
@ -225,25 +121,9 @@ export class FilePanel extends React.Component<Props, {}>
intent={Intent.SUCCESS}
onClick={this.BatchSend}
/>
<Button
disabled={this._isImporting}
icon="cloud-upload"
style={{ marginRight: 10 }}
text="导入"
intent={Intent.SUCCESS}
onClick={() =>
{
if (this.selectEl)
this.selectEl.click();
}}
/>
<input
ref={el => this.selectEl = el}
type="file"
style={{ display: "none" }}
multiple={true}
accept=".json,.cad"
onChange={(e) => this.handleImportFile(e.target.files)}
<ImportFile
commonPanel={this.commonPanel}
type={"file"}
/>
</>
);

@ -0,0 +1,193 @@
import { Button, Intent, ProgressBar } from "@blueprintjs/core";
import { observable } from "mobx";
import { observer } from "mobx-react";
import pako from "pako";
import React from "react";
import { CADFiler } from "../../../api";
import { app } from "../../../ApplicationServices/Application";
import { FileSystem } from '../../../Common/FileSystem';
import { TemplateUrls } from "../../../Common/HostUrl";
import { PostJson } from "../../../Common/Request";
import { StoreageKeys } from "../../../Common/StoreageKeys";
import { FileServer } from "../../../DatabaseServices/FileServer";
import { TopPanelStore } from "../../Store/TopPanelStore";
import { AppToaster } from "../Toaster";
import { CommonPanel } from "./CommonPanel";
@observer
export class ImportFile extends React.Component<{ commonPanel: CommonPanel, type: "file" | "template"; }>{
@observable private _isImporting = false;
selectEl = React.createRef<HTMLInputElement>();
handleImportFile = async (files: FileList) =>
{
let key = AppToaster.show({
message: <ProgressBar
className="docs-toast-progress"
intent={Intent.PRIMARY}
value={0 / files.length}
/>
});
this._isImporting = true;
const shopId = TopPanelStore.GetInstance().shopId;
const dir_id = this.props.commonPanel['currentDir'].id;
for (let i = 0, len = files.length; i < len; i++)
{
let f = files.item(i);
if (f.type === "application/json")
{
let dataStr = await FileSystem.ReadFileAsText(f);
if (!dataStr)
{
AppToaster.show({
message: f.name + "格式不正确",
timeout: 3000,
intent: Intent.DANGER
});
}
else
{
try
{
let { type } = JSON.parse(atob(dataStr));
if (!type && this.props.type === "file")
{
let { file, id } = JSON.parse(atob(dataStr));
if (!file || !id)
{
AppToaster.show({
message: f.name + "格式不正确",
timeout: 3000,
intent: Intent.DANGER
});
}
else if (shopId !== id && TopPanelStore.GetInstance().userName !== "cx")
{
AppToaster.show({
message: f.name + "不属于您的店铺,鉴权失败",
timeout: 3000,
intent: Intent.DANGER
});
}
else
{
let fserver = FileServer.GetInstance() as FileServer;
await fserver.UploadFile({
dir_id,
name: f.name.replace(".json", ""),
file: file
});
}
}
else if (type && type === this.props.type)
{
let { file, id, logo, props } = JSON.parse(atob(dataStr));
if (!file || !id || !logo || !props)
{
AppToaster.show({
message: f.name + "格式不正确",
timeout: 3000,
intent: Intent.DANGER
});
}
else if (shopId !== id && TopPanelStore.GetInstance().userName !== "cx")
{
AppToaster.show({
message: f.name + "不属于您的店铺,鉴权失败",
timeout: 3000,
intent: Intent.DANGER
});
}
else
{
await PostJson(TemplateUrls.create, {
name: f.name.replace(".json", ""),
dir_id,
logo,
props,
file,
zip_type: "gzip",
});
}
}
else
{
AppToaster.show({
message: f.name + "格式不正确",
timeout: 3000,
intent: Intent.DANGER
});
}
} catch (err)
{
AppToaster.show({
message: f.name + "格式不正确",
timeout: 3000,
intent: Intent.DANGER
});
}
}
}
else
{
try
{
let userName = localStorage.getItem(StoreageKeys.UserName);
if (userName === "cx")
{
let file = pako.inflate(new Uint8Array(await f.arrayBuffer()), { to: "string" });
app.OpenFile(new CADFiler(JSON.parse(file)));
}
return;
}
catch (error)
{
}
}
AppToaster.show({
message: <ProgressBar
stripes={i < len - 1}
className="docs-toast-progress"
intent={i === len - 1 ? Intent.SUCCESS : Intent.PRIMARY}
value={(i + 1) / files.length}
/>,
timeout: i === len - 1 ? 500 : 0
}, key);
}
await this.props.commonPanel.handleGetData();
this._isImporting = false;
this.selectEl.current.value = "";
};
render()
{
return (
<>
<Button
disabled={this._isImporting}
icon="cloud-upload"
style={{ marginRight: 10 }}
text="导入"
intent={Intent.SUCCESS}
onClick={() =>
{
if (this.selectEl.current)
this.selectEl.current.click();
}}
/>
<input
ref={this.selectEl}
type="file"
style={{ display: "none" }}
multiple={true}
accept=".json,.cad"
onChange={(e) => this.handleImportFile(e.target.files)}
/>
</>
);
}
}

@ -17,6 +17,7 @@ import { DuplicateRecordCloning } from '../../../Common/Status';
import { StoreageKeys } from '../../../Common/StoreageKeys';
import { Board } from '../../../DatabaseServices/Entity/Board';
import { Entity } from '../../../DatabaseServices/Entity/Entity';
import { FileServer } from '../../../DatabaseServices/FileServer';
import { HardwareCompositeEntity } from '../../../DatabaseServices/Hardware/HardwareCompositeEntity';
import { HardwareTopline } from '../../../DatabaseServices/Hardware/HardwareTopline';
import { PositioningBoardSpace } from '../../../DatabaseServices/Template/Positioning/PositioningBoardSpace';
@ -45,6 +46,7 @@ import { ModalHeader } from '../Modal/ModalContainer';
import { ModalState } from '../Modal/ModalInterface';
import { CommonPanel, IDirectoryProps } from '../SourceManage/CommonPanel';
import { HandleDirComponent } from '../SourceManage/HandleDirComponent';
import { ImportFile } from '../SourceManage/ImportFile';
import { AppToaster } from '../Toaster';
import { DeleteCurrentTempate, DeleteTempate } from './../../../DatabaseServices/Template/TempateUtils';
import { FilterVisualSpaceBox } from './../../../Geometry/SpaceParse/PointSelectSpace';
@ -82,6 +84,8 @@ export class TemplateManage extends React.Component<ITemplateManage, {}> {
@observable private currentTemplateInfo: IDrawerDoorTempInfo = { id: "", name: "", diy_logo: "" };
@observable private autoCutOption: IDrawBoardAutoCutOption = { isAutoCut: false, isRelevance: false };
private TemplateDrawHingeTool: TemplateDrawHingeTool;
commonPanel = React.createRef<CommonPanel>();
constructor(props)
{
super(props);
@ -103,6 +107,19 @@ export class TemplateManage extends React.Component<ITemplateManage, {}> {
}}
onClick={this.startCreateTemplate}
/>
<Button
icon="cloud-download"
style={{
marginRight: 10
}}
text="批量下载"
intent={Intent.SUCCESS}
onClick={this.handleMutDown}
/>
<ImportFile
commonPanel={this.commonPanel.current}
type={"template"}
/>
<Popover
position="bottom"
autoFocus
@ -157,6 +174,23 @@ export class TemplateManage extends React.Component<ITemplateManage, {}> {
/>
);
};
handleMutDown = async () =>
{
let server = FileServer.GetInstance() as FileServer;
let data = this.commonPanel.current.selectIds;
if (data.size === 0)
{
AppToaster.show({
message: "请选择要下载的文件",
timeout: 1500,
intent: Intent.DANGER
});
return;
}
for (let id of data)
await server.DownloadTemplate(id);
data.clear();
};
private startCreateTemplate = () =>
{
this.currentTemplateInfo.name = "";
@ -938,6 +972,7 @@ export class TemplateManage extends React.Component<ITemplateManage, {}> {
private renderTemplateList = () =>
{
return <CommonPanel
ref={this.commonPanel}
defaultDirId={DirectoryId.TemplateDir}
renderNav={this.renderNav}
renderMenuItems={this.renderMenuItems}

Loading…
Cancel
Save