From c39f6881152053ff4c4845d6ee67f1935aa5d315 Mon Sep 17 00:00:00 2001 From: SikongJueluo Date: Fri, 16 May 2025 16:38:57 +0800 Subject: [PATCH] fix: mother board reactive problem --- .justfile | 4 +- server/src/Controllers.cs | 176 +++-- server/src/DDSClient.cs | 170 +++++ src/APIClient.ts | 240 ++++++ src/components/PropertyEditor.vue | 2 +- src/components/PropertyPanel.vue | 70 +- src/components/UploadCard.vue | 23 +- .../equipments/DDSPropertyEditor.vue | 684 +++++++++++------- src/components/equipments/MotherBoard.vue | 69 +- src/components/equipments/MotherBoardCaps.vue | 55 +- src/stores/equipments.ts | 34 +- 11 files changed, 1063 insertions(+), 464 deletions(-) create mode 100644 server/src/DDSClient.cs diff --git a/.justfile b/.justfile index 8d4416a..b824b31 100644 --- a/.justfile +++ b/.justfile @@ -20,9 +20,7 @@ update: # 生成Restful API到网页客户端 gen-api: - cd server && dotnet run & - npx nswag openapi2tsclient /input:http://localhost:5000/swagger/v1/swagger.json /output:src/APIClient.ts - pkill server + npm run gen-api # 构建服务器,包含win与linux平台 [working-directory: "server"] diff --git a/server/src/Controllers.cs b/server/src/Controllers.cs index 7f17335..2a9f662 100644 --- a/server/src/Controllers.cs +++ b/server/src/Controllers.cs @@ -8,44 +8,6 @@ using WebProtocol; namespace server.Controllers; -// /// -// /// [TODO:description] -// /// -// public class HomeController : ControllerBase -// { -// private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); -// -// string INDEX_HTML_PATH = Path.Combine(Environment.CurrentDirectory, "index.html"); -// -// /// -// /// [TODO:description] -// /// -// /// [TODO:return] -// [HttpGet("/")] -// public IResult Index() -// { -// return TypedResults.Content("Hello", "text/html"); -// } -// -// // [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] -// // public IResult Error() -// // { -// // return TypedResults.Ok(); -// // } -// -// /// -// /// [TODO:description] -// /// -// /// [TODO:return] -// [HttpGet("/hello")] -// [HttpPost("/hello")] -// public IActionResult Hello() -// { -// string randomString = Guid.NewGuid().ToString(); -// return this.Ok($"Hello World! GUID: {randomString}"); -// } -// } - /// /// UDP API /// @@ -524,9 +486,9 @@ public class RemoteUpdater : ControllerBase /// 比特流位号 [HttpPost("DownloadBitstream")] [EnableCors("Users")] - [ProducesResponseType(typeof(bool),StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ArgumentException),StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(Exception),StatusCodes.Status500InternalServerError)] + [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ArgumentException), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] public async ValueTask UpdateBitstream(string address, int port, int bitstreamNum) { // 检查文件 @@ -543,7 +505,7 @@ public class RemoteUpdater : ControllerBase if (!fileBytes.IsSuccessful) return TypedResults.InternalServerError(fileBytes.Error); // 下载比特流 - var remoteUpdater = new RemoteUpdate.RemoteUpdateClient(address, port); + var remoteUpdater = new RemoteUpdateClient.RemoteUpdater(address, port); var ret = await remoteUpdater.UpdateBitstream(bitstreamNum, fileBytes.Value); if (ret.IsSuccessful) @@ -574,9 +536,9 @@ public class RemoteUpdater : ControllerBase /// 总共上传比特流的数量 [HttpPost("DownloadMultiBitstreams")] [EnableCors("Users")] - [ProducesResponseType(typeof(int),StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ArgumentException),StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(Exception),StatusCodes.Status500InternalServerError)] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ArgumentException), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] public async ValueTask DownloadMultiBitstreams(string address, int port, int? bitstreamNum) { // 检查文件 @@ -603,7 +565,7 @@ public class RemoteUpdater : ControllerBase } // 下载比特流 - var remoteUpdater = new RemoteUpdate.RemoteUpdateClient(address, port); + var remoteUpdater = new RemoteUpdateClient.RemoteUpdater(address, port); { var ret = await remoteUpdater.UploadBitstreams(bitstreams[0], bitstreams[1], bitstreams[2], bitstreams[3]); if (!ret.IsSuccessful) return TypedResults.InternalServerError(ret.Error); @@ -634,12 +596,12 @@ public class RemoteUpdater : ControllerBase /// 操作结果 [HttpPost("HotResetBitstream")] [EnableCors("Users")] - [ProducesResponseType(typeof(bool),StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ArgumentException),StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(Exception),StatusCodes.Status500InternalServerError)] + [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ArgumentException), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] public async ValueTask HotResetBitstream(string address, int port, int bitstreamNum) { - var remoteUpdater = new RemoteUpdate.RemoteUpdateClient(address, port); + var remoteUpdater = new RemoteUpdateClient.RemoteUpdater(address, port); var ret = await remoteUpdater.HotResetBitstream(bitstreamNum); if (ret.IsSuccessful) @@ -662,12 +624,12 @@ public class RemoteUpdater : ControllerBase /// [TODO:return] [HttpPost("GetFirmwareVersion")] [EnableCors("Users")] - [ProducesResponseType(typeof(UInt32),StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ArgumentException),StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(Exception),StatusCodes.Status500InternalServerError)] + [ProducesResponseType(typeof(UInt32), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ArgumentException), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] public async ValueTask GetFirmwareVersion(string address, int port) { - var remoteUpdater = new RemoteUpdate.RemoteUpdateClient(address, port); + var remoteUpdater = new RemoteUpdateClient.RemoteUpdater(address, port); var ret = await remoteUpdater.GetVersion(); if (ret.IsSuccessful) @@ -681,7 +643,111 @@ public class RemoteUpdater : ControllerBase return TypedResults.InternalServerError(ret.Error); } } - + +} + +/// +/// [TODO:description] +/// +[ApiController] +[Route("api/[controller]")] +public class DDSController : ControllerBase +{ + private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + + /// + /// [TODO:description] + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] + [HttpPost("SetWaveNum")] + [EnableCors("Users")] + [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ArgumentException), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] + public async ValueTask SetWaveNum(string address, int port, int channelNum, int waveNum) + { + var dds = new DDSClient.DDS(address, port); + + var ret = await dds.SetWaveNum(channelNum, waveNum); + if (ret.IsSuccessful) + { + logger.Info($"Device {address} set output wave num successfully"); + return TypedResults.Ok(ret.Value); + } + else + { + logger.Error(ret.Error); + return TypedResults.InternalServerError(ret.Error); + } + } + + /// + /// [TODO:description] + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] + [HttpPost("SetFreq")] + [EnableCors("Users")] + [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ArgumentException), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] + public async ValueTask SetFreq(string address, int port, int channelNum, int waveNum, UInt32 step) + { + var dds = new DDSClient.DDS(address, port); + + var ret = await dds.SetFreq(channelNum, waveNum, step); + if (ret.IsSuccessful) + { + logger.Info($"Device {address} set output freqency successfully"); + return TypedResults.Ok(ret.Value); + } + else + { + logger.Error(ret.Error); + return TypedResults.InternalServerError(ret.Error); + } + } + + /// + /// [TODO:description] + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] + [HttpPost("SetPhase")] + [EnableCors("Users")] + [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ArgumentException), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] + public async ValueTask SetPhase(string address, int port, int channelNum, int waveNum, int phase) + { + var dds = new DDSClient.DDS(address, port); + + var ret = await dds.SetPhase(channelNum, waveNum, phase); + if (ret.IsSuccessful) + { + logger.Info($"Device {address} set output phase successfully"); + return TypedResults.Ok(ret.Value); + } + else + { + logger.Error(ret.Error); + return TypedResults.InternalServerError(ret.Error); + } + + } + } diff --git a/server/src/DDSClient.cs b/server/src/DDSClient.cs new file mode 100644 index 0000000..4ecdb13 --- /dev/null +++ b/server/src/DDSClient.cs @@ -0,0 +1,170 @@ +using System.Net; +using DotNext; + +namespace DDSClient; + +static class DDSAddr +{ + /*地址定义:(以2路输出,4波形存储为例) + 00 R/W CHANNEL0 wave_sel + 01 R/W CHANNEL0 STORE0 freq_ctrl + 02 R/W CHANNEL0 STORE1 freq_ctrl + 03 R/W CHANNEL0 STORE2 freq_ctrl + 04 R/W CHANNEL0 STORE3 freq_ctrl + 05 R/W CHANNEL0 STORE0 phase_ctrl + 06 R/W CHANNEL0 STORE1 phase_ctrl + 07 R/W CHANNEL0 STORE2 phase_ctrl + 08 R/W CHANNEL0 STORE3 phase_ctrl + 09 R/W CHANNEL0 dds_wr_enable + 0A WO CHANNEL0 data + + 10 R/W CHANNEL1 wave_sel + 11 R/W CHANNEL1 STORE0 freq_ctrl + 12 R/W CHANNEL1 STORE1 freq_ctrl + 13 R/W CHANNEL1 STORE2 freq_ctrl + 14 R/W CHANNEL1 STORE3 freq_ctrl + 15 R/W CHANNEL1 STORE0 phase_ctrl + 16 R/W CHANNEL1 STORE1 phase_ctrl + 17 R/W CHANNEL1 STORE2 phase_ctrl + 18 R/W CHANNEL1 STORE3 phase_ctrl + 19 R/W CHANNEL1 dds_wr_enable + 1A WO CHANNEL1 data + */ + public const UInt32 Base = 0x4000_0000; + public static readonly ChannelAddr[] Channel = { new ChannelAddr(0x00), new ChannelAddr(0x10) }; + + public class ChannelAddr + { + private readonly UInt32 Offset; + public readonly UInt32 WaveSelect; + public readonly UInt32[] FreqCtrl; + public readonly UInt32[] PhaseCtrl; + public readonly UInt32 WriteEnable; + public readonly UInt32 WriteData; + + public ChannelAddr(UInt32 offset) + { + this.Offset = offset; + this.WaveSelect = Base + Offset + 0x00; + this.FreqCtrl = new UInt32[] + { + Base + offset + 0x01, + Base + offset + 0x02, + Base + offset + 0x03, + Base + offset + 0x04 + }; + this.PhaseCtrl = new UInt32[] { + Base + Offset + 0x05, + Base + Offset + 0x06, + Base + Offset + 0x07, + Base + Offset + 0x08 + }; + this.WriteEnable = Base + Offset + 0x09; + this.WriteData = Base + Offset + 0x0A; + } + } +} + +/// +/// [TODO:description] +/// +public class DDS +{ + private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + + readonly int timeout = 2000; + + readonly int port; + readonly string address; + private IPEndPoint ep; + + /// + /// [TODO:description] + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] + public DDS(string address, int port, int timeout = 2000) + { + if (timeout < 0) + throw new ArgumentException("Timeout couldn't be negative", nameof(timeout)); + this.address = address; + this.port = port; + this.ep = new IPEndPoint(IPAddress.Parse(address), port); + this.timeout = timeout; + } + + /// + /// [TODO:description] + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] + public async ValueTask> SetWaveNum(int channelNum, int waveNum) + { + if (channelNum < 0 || channelNum > 1) return new(new ArgumentException( + $"Channel number should be 0 ~ 1 instead of {channelNum}", nameof(channelNum))); + if (waveNum < 0 || waveNum > 3) return new(new ArgumentException( + $"Wave number should be 0 ~ 3 instead of {waveNum}", nameof(waveNum))); + + await MsgBus.UDPServer.ClearUDPData(this.address); + logger.Trace("Clear udp data finished"); + + var ret = await UDPClientPool.WriteAddr( + this.ep, DDSAddr.Channel[channelNum].WaveSelect, (UInt32)waveNum, this.timeout); + if (!ret.IsSuccessful) + return new(ret.Error); + return ret.Value; + } + + /// + /// [TODO:description] + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] + public async ValueTask> SetFreq(int channelNum, int waveNum, UInt32 step) + { + if (channelNum < 0 || channelNum > 1) return new(new ArgumentException( + $"Channel number should be 0 ~ 1 instead of {channelNum}", nameof(channelNum))); + if (waveNum < 0 || waveNum > 3) return new(new ArgumentException( + $"Wave number should be 0 ~ 3 instead of {waveNum}", nameof(waveNum))); + + await MsgBus.UDPServer.ClearUDPData(this.address); + logger.Trace("Clear udp data finished"); + + var ret = await UDPClientPool.WriteAddr( + this.ep, DDSAddr.Channel[channelNum].FreqCtrl[waveNum], step, this.timeout); + if (!ret.IsSuccessful) + return new(ret.Error); + return ret.Value; + } + + /// + /// [TODO:description] + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] + public async ValueTask> SetPhase(int channelNum, int waveNum, int phase) + { + if (channelNum < 0 || channelNum > 1) return new(new ArgumentException( + $"Channel number should be 0 ~ 1 instead of {channelNum}", nameof(channelNum))); + if (waveNum < 0 || waveNum > 3) return new(new ArgumentException( + $"Wave number should be 0 ~ 3 instead of {waveNum}", nameof(waveNum))); + if (phase < 0 || phase > 4096) return new(new ArgumentException( + $"Phase should be 0 ~ 4096 instead of {phase}", nameof(phase))); + + await MsgBus.UDPServer.ClearUDPData(this.address); + logger.Trace("Clear udp data finished"); + + var ret = await UDPClientPool.WriteAddr( + this.ep, DDSAddr.Channel[channelNum].PhaseCtrl[waveNum], (UInt32)phase, this.timeout); + if (!ret.IsSuccessful) + return new(ret.Error); + return ret.Value; + } +} diff --git a/src/APIClient.ts b/src/APIClient.ts index 3fa3f2c..2f14a10 100644 --- a/src/APIClient.ts +++ b/src/APIClient.ts @@ -1000,6 +1000,246 @@ export class RemoteUpdaterClient { } } +export class DDSClient { + private http: { fetch(url: RequestInfo, init?: RequestInit): Promise }; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise }) { + this.http = http ? http : window as any; + this.baseUrl = baseUrl ?? "http://localhost:5000"; + } + + /** + * [TODO:description] + * @param address (optional) [TODO:parameter] + * @param port (optional) [TODO:parameter] + * @param channelNum (optional) [TODO:parameter] + * @param waveNum (optional) [TODO:parameter] + * @return [TODO:return] + */ + setWaveNum(address: string | undefined, port: number | undefined, channelNum: number | undefined, waveNum: number | undefined): Promise { + let url_ = this.baseUrl + "/api/DDS/SetWaveNum?"; + if (address === null) + throw new Error("The parameter 'address' cannot be null."); + else if (address !== undefined) + url_ += "address=" + encodeURIComponent("" + address) + "&"; + if (port === null) + throw new Error("The parameter 'port' cannot be null."); + else if (port !== undefined) + url_ += "port=" + encodeURIComponent("" + port) + "&"; + if (channelNum === null) + throw new Error("The parameter 'channelNum' cannot be null."); + else if (channelNum !== undefined) + url_ += "channelNum=" + encodeURIComponent("" + channelNum) + "&"; + if (waveNum === null) + throw new Error("The parameter 'waveNum' cannot be null."); + else if (waveNum !== undefined) + url_ += "waveNum=" + encodeURIComponent("" + waveNum) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_: RequestInit = { + method: "POST", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processSetWaveNum(_response); + }); + } + + protected processSetWaveNum(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = resultData200 !== undefined ? resultData200 : null; + + return result200; + }); + } else if (status === 400) { + return response.text().then((_responseText) => { + let result400: any = null; + let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result400 = ArgumentException.fromJS(resultData400); + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + let result500: any = null; + let resultData500 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result500 = Exception.fromJS(resultData500); + return throwException("A server side error occurred.", status, _responseText, _headers, result500); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null as any); + } + + /** + * [TODO:description] + * @param address (optional) [TODO:parameter] + * @param port (optional) [TODO:parameter] + * @param channelNum (optional) [TODO:parameter] + * @param waveNum (optional) [TODO:parameter] + * @param step (optional) [TODO:parameter] + * @return [TODO:return] + */ + setFreq(address: string | undefined, port: number | undefined, channelNum: number | undefined, waveNum: number | undefined, step: number | undefined): Promise { + let url_ = this.baseUrl + "/api/DDS/SetFreq?"; + if (address === null) + throw new Error("The parameter 'address' cannot be null."); + else if (address !== undefined) + url_ += "address=" + encodeURIComponent("" + address) + "&"; + if (port === null) + throw new Error("The parameter 'port' cannot be null."); + else if (port !== undefined) + url_ += "port=" + encodeURIComponent("" + port) + "&"; + if (channelNum === null) + throw new Error("The parameter 'channelNum' cannot be null."); + else if (channelNum !== undefined) + url_ += "channelNum=" + encodeURIComponent("" + channelNum) + "&"; + if (waveNum === null) + throw new Error("The parameter 'waveNum' cannot be null."); + else if (waveNum !== undefined) + url_ += "waveNum=" + encodeURIComponent("" + waveNum) + "&"; + if (step === null) + throw new Error("The parameter 'step' cannot be null."); + else if (step !== undefined) + url_ += "step=" + encodeURIComponent("" + step) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_: RequestInit = { + method: "POST", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processSetFreq(_response); + }); + } + + protected processSetFreq(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = resultData200 !== undefined ? resultData200 : null; + + return result200; + }); + } else if (status === 400) { + return response.text().then((_responseText) => { + let result400: any = null; + let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result400 = ArgumentException.fromJS(resultData400); + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + let result500: any = null; + let resultData500 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result500 = Exception.fromJS(resultData500); + return throwException("A server side error occurred.", status, _responseText, _headers, result500); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null as any); + } + + /** + * [TODO:description] + * @param address (optional) [TODO:parameter] + * @param port (optional) [TODO:parameter] + * @param channelNum (optional) [TODO:parameter] + * @param waveNum (optional) [TODO:parameter] + * @param phase (optional) [TODO:parameter] + * @return [TODO:return] + */ + setPhase(address: string | undefined, port: number | undefined, channelNum: number | undefined, waveNum: number | undefined, phase: number | undefined): Promise { + let url_ = this.baseUrl + "/api/DDS/SetPhase?"; + if (address === null) + throw new Error("The parameter 'address' cannot be null."); + else if (address !== undefined) + url_ += "address=" + encodeURIComponent("" + address) + "&"; + if (port === null) + throw new Error("The parameter 'port' cannot be null."); + else if (port !== undefined) + url_ += "port=" + encodeURIComponent("" + port) + "&"; + if (channelNum === null) + throw new Error("The parameter 'channelNum' cannot be null."); + else if (channelNum !== undefined) + url_ += "channelNum=" + encodeURIComponent("" + channelNum) + "&"; + if (waveNum === null) + throw new Error("The parameter 'waveNum' cannot be null."); + else if (waveNum !== undefined) + url_ += "waveNum=" + encodeURIComponent("" + waveNum) + "&"; + if (phase === null) + throw new Error("The parameter 'phase' cannot be null."); + else if (phase !== undefined) + url_ += "phase=" + encodeURIComponent("" + phase) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_: RequestInit = { + method: "POST", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processSetPhase(_response); + }); + } + + protected processSetPhase(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = resultData200 !== undefined ? resultData200 : null; + + return result200; + }); + } else if (status === 400) { + return response.text().then((_responseText) => { + let result400: any = null; + let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result400 = ArgumentException.fromJS(resultData400); + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + }); + } else if (status === 500) { + return response.text().then((_responseText) => { + let result500: any = null; + let resultData500 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result500 = Exception.fromJS(resultData500); + return throwException("A server side error occurred.", status, _responseText, _headers, result500); + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null as any); + } +} + export class DataClient { private http: { fetch(url: RequestInfo, init?: RequestInit): Promise }; private baseUrl: string; diff --git a/src/components/PropertyEditor.vue b/src/components/PropertyEditor.vue index b5d3ab8..ec8ae16 100644 --- a/src/components/PropertyEditor.vue +++ b/src/components/PropertyEditor.vue @@ -152,7 +152,7 @@ const emit = defineEmits<{ }>(); // 控制折叠面板状态 -const generalPropsExpanded = ref(true); +const generalPropsExpanded = ref(false); const componentPropsExpanded = ref(true); // 更新组件属性方法 diff --git a/src/components/PropertyPanel.vue b/src/components/PropertyPanel.vue index dedaef5..fa6c397 100644 --- a/src/components/PropertyPanel.vue +++ b/src/components/PropertyPanel.vue @@ -45,18 +45,10 @@
- -
- 该组件没有提供特殊功能 -
-
-
- 选择元件以查看其功能 + +
该组件没有提供特殊功能
+
选择元件以查看其功能
@@ -98,7 +90,7 @@ const props = defineProps<{ }>(); // 控制各个属性分区的展开状态 -const propertySectionExpanded = ref(true); // 基本属性区域默认展开 +const propertySectionExpanded = ref(false); // 基本属性区域默认展开 const pinsSectionExpanded = ref(false); // 引脚配置区域默认折叠 const componentCapsExpanded = ref(true); // 组件功能区域默认展开 const wireSectionExpanded = ref(false); // 连线管理区域默认折叠 @@ -225,10 +217,10 @@ async function getExposedCapabilities(componentType: string) { // 动态导入组件 const module = await import(`./equipments/${componentType}.vue`); const Component = module.default; - + // 创建一个临时div作为挂载点 - const tempDiv = document.createElement('div'); - + const tempDiv = document.createElement("div"); + // 创建临时应用实例并挂载组件 let exposedMethods: any = null; const app = createApp({ @@ -239,33 +231,36 @@ async function getExposedCapabilities(componentType: string) { // 获取组件实例暴露的方法 exposedMethods = el; } - } + }, }); - } + }, }); - + // 挂载应用 const vm = app.mount(tempDiv); - + // 确保实例已创建并获取到暴露的方法 - await new Promise(resolve => setTimeout(resolve, 0)); - + await new Promise((resolve) => setTimeout(resolve, 0)); + // 检查是否有getCapabilities方法 - if (exposedMethods && typeof exposedMethods.getCapabilities === 'function') { + if ( + exposedMethods && + typeof exposedMethods.getCapabilities === "function" + ) { // 获取能力组件定义 const CapabilityComponent = exposedMethods.getCapabilities(); - + // 卸载应用,清理DOM app.unmount(); tempDiv.remove(); - + return CapabilityComponent; } - + // 卸载应用,清理DOM app.unmount(); tempDiv.remove(); - + return null; } catch (error) { console.error(`获取${componentType}能力页面失败:`, error); @@ -280,26 +275,31 @@ watch( if (newComponentData && newComponentData.type) { try { // 首先尝试从实例中获取暴露的方法 - const capsComponent = await getExposedCapabilities(newComponentData.type); - + const capsComponent = await getExposedCapabilities( + newComponentData.type, + ); + if (capsComponent) { capabilityComponent.value = markRaw(capsComponent); console.log(`已从实例加载${newComponentData.type}组件的能力页面`); return; } - + // 如果实例方法获取失败,回退到模块导出方法 - const module = await import(`./equipments/${newComponentData.type}.vue`); - + const module = await import( + `./equipments/${newComponentData.type}.vue` + ); + if ( - (module.default && typeof module.default.getCapabilities === "function") || + (module.default && + typeof module.default.getCapabilities === "function") || typeof module.getCapabilities === "function" ) { const getCapsFn = typeof module.getCapabilities === "function" ? module.getCapabilities : module.default.getCapabilities; - + const moduleCapComponent = getCapsFn(); if (moduleCapComponent) { capabilityComponent.value = markRaw(moduleCapComponent); @@ -307,7 +307,7 @@ watch( return; } } - + capabilityComponent.value = null; console.log(`组件${newComponentData.type}没有提供getCapabilities方法`); } catch (error) { @@ -318,7 +318,7 @@ watch( capabilityComponent.value = null; } }, - { immediate: true } + { immediate: true }, ); // 修改hasComponentCaps计算属性 diff --git a/src/components/UploadCard.vue b/src/components/UploadCard.vue index afe046a..4c59ae5 100644 --- a/src/components/UploadCard.vue +++ b/src/components/UploadCard.vue @@ -6,26 +6,27 @@
选择或拖拽上传文件 - +
-
diff --git a/src/components/equipments/DDSPropertyEditor.vue b/src/components/equipments/DDSPropertyEditor.vue index 2ea5a43..b0540e9 100644 --- a/src/components/equipments/DDSPropertyEditor.vue +++ b/src/components/equipments/DDSPropertyEditor.vue @@ -1,4 +1,5 @@ -