!2807 优化:文件历史记录数据匹配算法优化

pull/2806/MERGE
林三 4 months ago committed by ChenX
parent 2ef0152036
commit 9fd4791230

@ -1,15 +1,11 @@
import { Button, Checkbox, HTMLTable, Intent } from "@blueprintjs/core";
import { Checkbox } from "@blueprintjs/core";
import { observable } from "mobx";
import { observer } from "mobx-react";
import React from "react";
import { app } from "../../ApplicationServices/Application";
import { StoreageKeys } from "../../Common/StoreageKeys";
import { FileServer } from "../../DatabaseServices/FileServer";
import { userConfig } from "../../Editor/UserConfig";
import { BoardModalType } from "../../UI/Components/Board/BoardModalType";
import { ModalState } from "../../UI/Components/Modal/ModalInterface";
import { AppToaster } from "../../UI/Components/Toaster";
import { userConfigStore } from "../../UI/Store/UserConfigStore";
import { OpenHistoryList } from "./OpenHistoryList";
import { HistoryProp } from "./OperLogsModal";
@observer
@ -60,7 +56,6 @@ export class OpenHistoryBody extends React.Component<HistoryProp, {}>
userName={this.props.userName}
files={this.props.files}
data={this.props.data}
OnClickOpenFile={this.props.OnClickOpenFile}
/>
</div>
</div>
@ -90,204 +85,3 @@ export class OpenHistoryBody extends React.Component<HistoryProp, {}>
);
}
}
@observer
export class OpenHistoryList extends React.Component<HistoryProp, {}>
{
_Index = 0;
_LastOper = "";
_Data = this.props.data;
@observable _CanOpen: boolean = false;
constructor(props)
{
super(props);
if (this.props.newFileId)
this._CanOpen = true;
}
render()
{
return (
<HTMLTable bordered={true} interactive={true} style={{ lineHeight: 0.5, width: "100%", padding: "5px 5px 0px 5px", border: "1px solid #DBDCDD" }}>
<thead>
<tr>
<th style={{ width: 50 }}></th>
<th style={{ width: 190 }}></th>
<th>
<Checkbox
label="只显示能还原记录"
style={{ position: 'absolute', right: "10px", fontSize: "12px", top: "15px" }}
checked={this._CanOpen}
onClick={(e) =>
{
this._Index = 0;
this._LastOper = "";
this._CanOpen = !this._CanOpen;
e.currentTarget.blur();
}}
/>
</th>
</tr>
</thead>
<tbody>
{
this._CanOpen ? this._CanOpenDataList() : this._AllDataList()
}
</tbody>
</HTMLTable>
);
}
_AllDataList = () =>
{
let count = 0;
return (
<>
{
this._Data.map(d =>
{
if (d.oper_type_name === "打开")
if (this._LastOper === "打开")
return;
this._LastOper = d.oper_type_name;
if (d.oper_type_name === "修改")
count++;
if (this.props.newFileId && count > 5) return;
return <tr key={d.oper_date}>
<td>{d.oper_type_name}</td>
<td
style={{
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
maxWidth: 150
}}
title={`${d.oper_user}`}
>
{d.oper_user}
</td>
<td>
{d.oper_date}
{this._ButtonEl(d.oper_type_name, d.oper_date, this.props.files[this._Index])}
</td>
</tr>;
})
}
</>
);
};
_CanOpenDataList = () =>
{
let count = 0;
return (
<>
{
this._Data.map((d, i) =>
{
if (d.oper_type_name !== "新建" && d.oper_type_name !== "修改") return;
if (!this._HasHistoryFile(d.oper_type_name, d.oper_date, this.props.files[this._Index])) return;
count++;
if (this.props.newFileId && count > 5) return;
return <tr>
<td>{d.oper_type_name}</td>
<td
style={{
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
maxWidth: 150
}}
title={`${d.oper_user}`}
>
{d.oper_user}
</td>
<td>
{d.oper_date}
<Button
className="histroyBtn"
value={this._Index++}
text="打开"
onClick={(e) =>
{
let index = e.currentTarget.value;
this.handleOpen(index);
}}
/>
</td>
</tr>;
})
}
</>
);
};
handleOpen = async (index: number) =>
{
const { fileId, newFileId, files, userName } = this.props;
let status: boolean = true;
if (newFileId)
{
let server = FileServer.GetInstance();
if (fileId != newFileId)
{
server._CurrentFilePath = "";
server.m_CurFileId = newFileId;
let info = await server.GetFileInfo(newFileId);
server.CurrentFileMd5 = info.code;
if (info.name)
server.currentFileInfo.name = info.name;
localStorage.setItem(StoreageKeys.LastOpenFileId, info.file_id || "");
}
status = await this.props.OnClickOpenFile(userName, newFileId, files, index);
}
else
{
status = await this.props.OnClickOpenFile(userName, fileId, files, index);
}
if (!status)
{
AppToaster.show({
message: "打开图纸失败,请尝试打开其他历史记录图纸",
timeout: 3000,
intent: Intent.DANGER,
});
return;
}
if (this.props.isNotToaster)
app.Editor.ModalManage.m_PromisRes({ Status: ModalState.Ok });
app.Editor.ModalManage.Destory();
};
_ButtonEl(name: string, oper_date: string, file_date: string): React.ReactElement<any>
{
if (!this._HasHistoryFile(name, oper_date, file_date)) return;
return (
<Button
className="histroyBtn"
value={this._Index++}
text="打开"
onClick={async (e) =>
{
let index = e.currentTarget.value;
this.handleOpen(index);
}}
/>
);
}
//验证是否有可以打开的历史文件
_HasHistoryFile(name: string, oper_date: string, file_date: string)
{
if (this._Index >= this.props.files.length) return;
if (name !== "修改" && name !== "新建") return;
let date = new Date(oper_date);
let operDate = date.getHours() * 60 * 60 + date.getMinutes() * 60 + date.getSeconds(); //时分秒转换number 好比较
let fileDateStr = file_date.split("-");
let fileDate = parseInt(fileDateStr[fileDateStr.length - 3]) * 60 * 60 + parseInt(fileDateStr[fileDateStr.length - 2]) * 60 + parseInt(fileDateStr[fileDateStr.length - 1]); //时分秒转换number 好比较
if (!(operDate - 10 <= fileDate && fileDate <= operDate + 10)) return false; //误差±10秒
else return true;
}
}

@ -0,0 +1,265 @@
import { Button, Checkbox, HTMLTable, Intent } from "@blueprintjs/core";
import { observable } from "mobx";
import { observer } from "mobx-react";
import React from "react";
import { app } from "../../ApplicationServices/Application";
import { FileHistoryFilesUrl, FileUrls } from "../../Common/HostUrl";
import { PostJson, RequestStatus } from "../../Common/Request";
import { StoreageKeys } from "../../Common/StoreageKeys";
import { FileServer } from "../../DatabaseServices/FileServer";
import { ModalState } from "../../UI/Components/Modal/ModalInterface";
import { AppToaster } from "../../UI/Components/Toaster";
import { FetchFile1 } from "./OperLog";
import { HistoryProp } from "./OperLogsModal";
@observer
export class OpenHistoryList extends React.Component<HistoryProp, {}>
{
LastOper = "";
CanOpenFileDataMap: Map<number, number> = new Map(); //this.props.data -> this.props.files
@observable CanOpen: boolean = false;
constructor(props)
{
super(props);
if (this.props.newFileId)
this.CanOpen = true;
this.ParseData();
}
ParseData = () =>
{
for (let i = 0, j = 0; j < this.props.data.length; j++)
{
if (i >= this.props.files.length)
break;
let data = this.props.data[j];
if (data.oper_type_name !== "修改" && data.oper_type_name !== "新建")
continue;
let date = new Date(data.oper_date);
let timeNum =
(date.getMonth() + 1) * Math.pow(60, 4) +
date.getDate() * Math.pow(60, 3) +
date.getHours() * Math.pow(60, 2) +
date.getMinutes() * 60 +
date.getSeconds(); //时分秒转换number 好比较
for (; i < this.props.files.length; i++)
{
let canOpenFile = this.props.files[i];
let str = canOpenFile.split("-");
let canOpenFileDateNum =
parseInt(str[str.length - 5]) * Math.pow(60, 4) +
parseInt(str[str.length - 4]) * Math.pow(60, 3) +
parseInt(str[str.length - 3]) * Math.pow(60, 2) +
parseInt(str[str.length - 2]) * 60 +
parseInt(str[str.length - 1]); //时分秒转换number 好比较
if (canOpenFileDateNum - 10 > timeNum)
continue;
if (Math.abs(timeNum - canOpenFileDateNum) < 10)
this.CanOpenFileDataMap.set(j, i++);
break;
}
}
};
AllDataList = () =>
{
let count = 0;
return (
<>
{
this.props.data.map((data, i) =>
{
if (data.oper_type_name === "打开")
if (this.LastOper === "打开")
return;
this.LastOper = data.oper_type_name;
if (data.oper_type_name === "修改")
count++;
if (this.props.newFileId && count > 20) return;
let canOpenFileIndex = this.CanOpenFileDataMap.get(i);
let file = this.props.files[canOpenFileIndex];
return <tr key={data.oper_date}>
<td>{data.oper_type_name}</td>
<td
style={{
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
maxWidth: 150
}}
title={`${data.oper_user}`}
>
{data.oper_user}
</td>
<td>
{data.oper_date}
{
file && <Button
className="histroyBtn"
value={file}
text="打开"
onClick={async (e) =>
{
this.HandleOpen(e.currentTarget.value);
}}
/>
}
</td>
</tr>;
})
}
</>
);
};
CanOpenDataList = () =>
{
let count = 0;
return (
<>
{
this.props.data.map((data, i) =>
{
if (data.oper_type_name !== "新建" && data.oper_type_name !== "修改") return;
let canOpenFileIndex = this.CanOpenFileDataMap.get(i);
let file = this.props.files[canOpenFileIndex];
if (file)
{
count++;
if (this.props.newFileId && count > 20) return;
return <tr>
<td>{data.oper_type_name}</td>
<td
style={{
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
maxWidth: 150
}}
title={`${data.oper_user}`}
>
{data.oper_user}
</td>
<td>
{data.oper_date}
<Button
className="histroyBtn"
value={file}
text="打开"
onClick={(e) =>
{
this.HandleOpen(e.currentTarget.value);
}} />
</td>
</tr>;
}
})
}
</>
);
};
HandleOpen = async (fileTitle: string) =>
{
const { fileId, newFileId, files, userName } = this.props;
let status: boolean = true;
if (newFileId)
{
let server = FileServer.GetInstance();
if (fileId != newFileId)
{
server._CurrentFilePath = "";
server.m_CurFileId = newFileId;
let code = await server.GetFileMD5(newFileId);
if (code)
{
let data = await PostJson(FileUrls.detail, { file_id: newFileId });
if (data.err_code === RequestStatus.Ok && data.files?.name)
{
server.currentFileInfo.name = data.files.name;
server.CurrentFileMd5 = code;
}
localStorage.setItem(StoreageKeys.LastOpenFileId, data.files?.file_id || "");
}
}
status = await this.OnClickOpenFile(userName, newFileId, fileTitle);
}
else
{
status = await this.OnClickOpenFile(userName, fileId, fileTitle);
}
if (!status)
{
AppToaster.show({
message: "打开图纸失败,请尝试打开其他历史记录图纸",
timeout: 3000,
intent: Intent.DANGER,
});
return;
}
if (this.props.isNotToaster)
app.Editor.ModalManage.m_PromisRes({ Status: ModalState.Ok });
app.Editor.ModalManage.Destory();
};
OnClickOpenFile = async (userName: string, fileId: string, fileTitle: string) =>
{
try
{
let url = FileHistoryFilesUrl + encodeURIComponent(userName + "//" + fileId + "//" + fileTitle);
let cadf = await FetchFile1(url + ".cad");
app.OpenFile(cadf);
return true;
}
catch {
return false;
}
};
render()
{
return (
<HTMLTable bordered={true} interactive={true} style={{ lineHeight: 0.5, width: "100%", padding: "5px 5px 0px 5px", border: "1px solid #DBDCDD" }}>
<thead>
<tr>
<th style={{ width: 50 }}></th>
<th style={{ width: 190 }}></th>
<th>
<Checkbox
label="只显示能还原记录"
style={{ position: 'absolute', right: "10px", fontSize: "12px", top: "15px" }}
checked={this.CanOpen}
onClick={(e) =>
{
this.LastOper = "";
this.CanOpen = !this.CanOpen;
e.currentTarget.blur();
}} />
</th>
</tr>
</thead>
<tbody>
{this.CanOpen ? this.CanOpenDataList() : this.AllDataList()}
</tbody>
</HTMLTable>
);
}
}

@ -1,7 +1,7 @@
import { Intent, Toaster } from "@blueprintjs/core";
import React from "react";
import { app } from "../../ApplicationServices/Application";
import { FileHistoryFilesUrl, FileHistoryUrl, SignUrl } from "../../Common/HostUrl";
import { FileHistoryUrl, SignUrl } from "../../Common/HostUrl";
import { PostJson, RequestStatus } from "../../Common/Request";
import { StoreageKeys } from "../../Common/StoreageKeys";
import { inflateBase64 } from "../../Common/inflate";
@ -109,7 +109,6 @@ export class OperLogs implements Command
files: allFiles,
data: data,
fileName: this.fileName,
OnClickOpenFile: this.OnClickOpenFile,
isNotToaster: true,
});
let Rm = await app.Editor.ModalManage.Wait();
@ -131,30 +130,12 @@ export class OperLogs implements Command
time={time}
isOpenFile={this._IsOpenFile}
Toaster={HistoryToaster}
OnClickOpenFile={this.OnClickOpenFile}
/>,
timeout: time + 500,
intent: Intent.NONE,
});
return true;
}
//打开历史保存的文件图纸
private async OnClickOpenFile(userName: string, fileId: string, files: string[], number: number)
{
try
{
let fileName = files[number];
let url = FileHistoryFilesUrl + encodeURIComponent(userName + "//" + fileId + "//" + fileName);
let cadf = await FetchFile1(url + ".cad");
app.OpenFile(cadf);
return true;
}
catch
{
return false;
}
}
}
export async function FetchFile1(url: string): Promise<CADFiler>

@ -2,7 +2,7 @@ import { Button, Classes, Icon, IToaster } from "@blueprintjs/core";
import { observer } from "mobx-react";
import React from "react";
import { app } from "../../ApplicationServices/Application";
import { OpenHistoryList } from "./OpenHistoryBody";
import { OpenHistoryList } from "./OpenHistoryList";
export interface OperInfo
{
@ -23,7 +23,6 @@ export interface HistoryProp
time?: number,
Toaster?: IToaster;
newFileId?: string;//右键打开历史记录时文件id
OnClickOpenFile: (userName: string, fileId: string, files: string[], number: number) => Promise<boolean>;
}
@observer
@ -60,7 +59,6 @@ export class OperLogsModal extends React.Component<HistoryProp, {}>
files={this.props.files}
newFileId={this.props.newFileId}
data={this.props.data}
OnClickOpenFile={this.props.OnClickOpenFile}
isNotToaster={this.props.isNotToaster}
/>
</div>

@ -295,7 +295,7 @@ export class FileServer extends Singleton
else
{
let data = await PostJson(FileUrls.detail, { file_id: fid });
if (data.err_code === RequestStatus.Ok && data.files)
if (data.err_code === RequestStatus.Ok && data.files?.file)
{
let f: IFileInfo = {
name: data.files.name,

Loading…
Cancel
Save