diff --git a/Backend/Backend.csproj b/Backend/Backend.csproj index e3c1125..ae412bd 100644 --- a/Backend/Backend.csproj +++ b/Backend/Backend.csproj @@ -18,6 +18,7 @@ + diff --git a/Backend/Controllers/BuildInfoController.cs b/Backend/Controllers/BuildInfoController.cs index a1cea3f..e64cce8 100644 --- a/Backend/Controllers/BuildInfoController.cs +++ b/Backend/Controllers/BuildInfoController.cs @@ -104,22 +104,43 @@ namespace Backend.Controllers //新增 //抓取當前的Priority var current_priority = await backendRepository.GetCurrentPriority("building"); - var map_3d_guid = new Guid(); + var map_3d_guid = Guid.NewGuid(); - Dictionary building = new Dictionary(); - building = new Dictionary() + if (post.urn_3D != null) { - { "@building_tag", post.building_tag}, - { "@full_name", post.Full_name}, - { "@ip_address", post.Ip_address}, - { "@ip_port", post.Ip_port}, - { "@priority", current_priority + 1}, - { "@orgName_3D", post.orgName_3D}, - { "@saveName_3D", map_3d_guid}, - { "@extName_3D", post.extName_3D}, - { "@created_by", myUserInfo.Userinfo_guid} - }; - await backendRepository.AddOneByCustomTable(building, "building"); + Dictionary building = new Dictionary(); + building = new Dictionary() + { + { "@building_tag", post.building_tag}, + { "@full_name", post.Full_name}, + { "@ip_address", post.Ip_address}, + { "@ip_port", post.Ip_port}, + { "@priority", current_priority + 1}, + { "@orgName_3D", post.orgName_3D}, + { "@saveName_3D", map_3d_guid}, + { "@extName_3D", post.extName_3D}, + { "@urn_3D", post.urn_3D}, + { "@created_by", myUserInfo.Userinfo_guid} + }; + await backendRepository.AddOneByCustomTable(building, "building"); + } + else + { + Dictionary building = new Dictionary(); + building = new Dictionary() + { + { "@building_tag", post.building_tag}, + { "@full_name", post.Full_name}, + { "@ip_address", post.Ip_address}, + { "@ip_port", post.Ip_port}, + { "@priority", current_priority + 1}, + { "@orgName_3D", post.orgName_3D}, + { "@saveName_3D", map_3d_guid}, + { "@extName_3D", post.extName_3D}, + { "@created_by", myUserInfo.Userinfo_guid} + }; + await backendRepository.AddOneByCustomTable(building, "building"); + } if (post.orgName_3D != null && post.extName_3D != null) { @@ -186,18 +207,38 @@ namespace Backend.Controllers if (!judgeIPAddressRepeat) { - Dictionary building = new Dictionary(); - building = new Dictionary() + if (post.urn_3D != null) { - { "@full_name", post.Full_name}, - { "@ip_address", post.Ip_address}, - { "@ip_port", post.Ip_port}, - { "@orgName_3D", post.orgName_3D}, - { "@extName_3D", post.extName_3D}, - { "@updated_by", myUserInfo.Userinfo_guid}, - { "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} - }; - await backendRepository.UpdateOneByCustomTable(building, "building", "building_tag='" + post.building_tag + "'"); + Dictionary building = new Dictionary(); + building = new Dictionary() + { + { "@full_name", post.Full_name}, + { "@ip_address", post.Ip_address}, + { "@ip_port", post.Ip_port}, + { "@orgName_3D", post.orgName_3D}, + { "@extName_3D", post.extName_3D}, + { "@urn_3D", post.urn_3D}, + { "@updated_by", myUserInfo.Userinfo_guid}, + { "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} + }; + await backendRepository.UpdateOneByCustomTable(building, "building", "building_tag='" + post.building_tag + "'"); + } + else + { + Dictionary building = new Dictionary(); + building = new Dictionary() + { + { "@full_name", post.Full_name}, + { "@ip_address", post.Ip_address}, + { "@ip_port", post.Ip_port}, + { "@orgName_3D", post.orgName_3D}, + { "@extName_3D", post.extName_3D}, + { "@updated_by", myUserInfo.Userinfo_guid}, + { "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} + }; + await backendRepository.UpdateOneByCustomTable(building, "building", "building_tag='" + post.building_tag + "'"); + } + if (post.orgName_3D != null && post.extName_3D != null) { diff --git a/Backend/Controllers/ModelDerivativeController.cs b/Backend/Controllers/ModelDerivativeController.cs new file mode 100644 index 0000000..951cae1 --- /dev/null +++ b/Backend/Controllers/ModelDerivativeController.cs @@ -0,0 +1,53 @@ +using Autodesk.Forge; +using Autodesk.Forge.Model; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace forgeSample.Controllers +{ + [ApiController] + public class ModelDerivativeController : ControllerBase + { + /// + /// Start the translation job for a give bucketKey/objectName + /// + /// + /// + [HttpPost] + [Route("api/forge/modelderivative/jobs")] + public async Task TranslateObject([FromBody] TranslateObjectModel objModel) + { + dynamic oauth = await OAuthController.GetInternalAsync(); + + // prepare the payload + List outputs = new List() + { + new JobPayloadItem( + JobPayloadItem.TypeEnum.Svf, + new List() + { + JobPayloadItem.ViewsEnum._2d, + JobPayloadItem.ViewsEnum._3d + }) + }; + JobPayload job; + job = new JobPayload(new JobPayloadInput(objModel.objectName), new JobPayloadOutput(outputs)); + + // start the translation + DerivativesApi derivative = new DerivativesApi(); + derivative.Configuration.AccessToken = oauth.access_token; + dynamic jobPosted = await derivative.TranslateAsync(job); + return jobPosted; + } + + /// + /// Model for TranslateObject method + /// + public class TranslateObjectModel + { + public string bucketKey { get; set; } + public string objectName { get; set; } + } + } +} diff --git a/Backend/Controllers/OAuthController.cs b/Backend/Controllers/OAuthController.cs new file mode 100644 index 0000000..ddf54b5 --- /dev/null +++ b/Backend/Controllers/OAuthController.cs @@ -0,0 +1,70 @@ +using Autodesk.Forge; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Threading.Tasks; + +namespace forgeSample.Controllers +{ + [ApiController] + public class OAuthController : ControllerBase + { + // As both internal & public tokens are used for all visitors + // we don't need to request a new token on every request, so let's + // cache them using static variables. Note we still need to refresh + // them after the expires_in time (in seconds) + private static dynamic InternalToken { get; set; } + private static dynamic PublicToken { get; set; } + + /// + /// Get access token with public (viewables:read) scope + /// + [HttpGet] + [Route("api/forge/oauth/token")] + public async Task GetPublicAsync() + { + if (PublicToken == null || PublicToken.ExpiresAt < DateTime.UtcNow) + { + PublicToken = await Get2LeggedTokenAsync(new Scope[] { Scope.ViewablesRead }); + PublicToken.ExpiresAt = DateTime.UtcNow.AddSeconds(PublicToken.expires_in); + } + return PublicToken; + } + + /// + /// Get access token with internal (write) scope + /// + public static async Task GetInternalAsync() + { + if (InternalToken == null || InternalToken.ExpiresAt < DateTime.UtcNow) + { + InternalToken = await Get2LeggedTokenAsync(new Scope[] { Scope.BucketCreate, Scope.BucketRead, Scope.BucketDelete, Scope.DataRead, Scope.DataWrite, Scope.DataCreate, Scope.CodeAll }); + InternalToken.ExpiresAt = DateTime.UtcNow.AddSeconds(InternalToken.expires_in); + } + + return InternalToken; + } + + /// + /// Get the access token from Autodesk + /// + private static async Task Get2LeggedTokenAsync(Scope[] scopes) + { + TwoLeggedApi oauth = new TwoLeggedApi(); + string grantType = "client_credentials"; + dynamic bearer = await oauth.AuthenticateAsync( + GetAppSetting("FORGE_CLIENT_ID"), + GetAppSetting("FORGE_CLIENT_SECRET"), + grantType, + scopes); + return bearer; + } + + /// + /// Reads appsettings from web.config + /// + public static string GetAppSetting(string settingKey) + { + return Environment.GetEnvironmentVariable(settingKey).Trim(); + } + } +} \ No newline at end of file diff --git a/Backend/Controllers/OSSController.cs b/Backend/Controllers/OSSController.cs new file mode 100644 index 0000000..6a5cb26 --- /dev/null +++ b/Backend/Controllers/OSSController.cs @@ -0,0 +1,150 @@ +using Autodesk.Forge; +using Autodesk.Forge.Model; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace forgeSample.Controllers +{ + [ApiController] + public class OSSController : ControllerBase + { + private IWebHostEnvironment _env; + public OSSController(IWebHostEnvironment env) { _env = env; } + public string ClientId { get { return OAuthController.GetAppSetting("FORGE_CLIENT_ID").ToLower(); } } + + /// + /// Return list of buckets (id=#) or list of objects (id=bucketKey) + /// + [HttpGet] + [Route("api/forge/oss/buckets")] + public async Task> GetOSSAsync(string id) + { + IList nodes = new List(); + dynamic oauth = await OAuthController.GetInternalAsync(); + + if (id == "#") // root + { + // in this case, let's return all buckets + BucketsApi appBckets = new BucketsApi(); + appBckets.Configuration.AccessToken = oauth.access_token; + + // to simplify, let's return only the first 100 buckets + dynamic buckets = await appBckets.GetBucketsAsync("US", 100); + foreach (KeyValuePair bucket in new DynamicDictionaryItems(buckets.items)) + { + nodes.Add(new TreeNode(bucket.Value.bucketKey, bucket.Value.bucketKey.Replace(ClientId + "-", string.Empty), "bucket", true)); + } + } + else + { + // as we have the id (bucketKey), let's return all + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = oauth.access_token; + var objectsList = await objects.GetObjectsAsync(id, 100); + foreach (KeyValuePair objInfo in new DynamicDictionaryItems(objectsList.items)) + { + nodes.Add(new TreeNode(Base64Encode((string)objInfo.Value.objectId), + objInfo.Value.objectKey, "object", false)); + } + } + return nodes; + } + + /// + /// Model data for jsTree used on GetOSSAsync + /// + public class TreeNode + { + public TreeNode(string id, string text, string type, bool children) + { + this.id = id; + this.text = text; + this.type = type; + this.children = children; + } + + public string id { get; set; } + public string text { get; set; } + public string type { get; set; } + public bool children { get; set; } + } + + /// + /// Create a new bucket + /// + [HttpPost] + [Route("api/forge/oss/buckets")] + public async Task CreateBucket([FromBody] CreateBucketModel bucket) + { + BucketsApi buckets = new BucketsApi(); + dynamic token = await OAuthController.GetInternalAsync(); + buckets.Configuration.AccessToken = token.access_token; + PostBucketsPayload bucketPayload = new PostBucketsPayload(string.Format("{0}-{1}", ClientId, bucket.bucketKey.ToLower()), null, + PostBucketsPayload.PolicyKeyEnum.Transient); + return await buckets.CreateBucketAsync(bucketPayload, "US"); + } + + /// + /// Input model for CreateBucket method + /// + public class CreateBucketModel + { + public string bucketKey { get; set; } + } + + /// + /// Receive a file from the client and upload to the bucket + /// + /// + [HttpPost] + [Route("api/forge/oss/objects")] + public async Task UploadObject([FromForm] UploadFile input) + { + // save the file on the server + var fileSavePath = Path.Combine(_env.WebRootPath, Path.GetFileName(input.fileToUpload.FileName)); + using (var stream = new FileStream(fileSavePath, FileMode.Create)) + await input.fileToUpload.CopyToAsync(stream); + + + // get the bucket... + dynamic oauth = await OAuthController.GetInternalAsync(); + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = oauth.access_token; + + // upload the file/object, which will create a new object + dynamic uploadedObj; + using (StreamReader streamReader = new StreamReader(fileSavePath)) + { + uploadedObj = await objects.UploadObjectAsync(input.bucketKey, + Path.GetFileName(input.fileToUpload.FileName), (int)streamReader.BaseStream.Length, streamReader.BaseStream, + "application/octet-stream"); + } + + // cleanup + System.IO.File.Delete(fileSavePath); + string urn = Base64Encode((string)uploadedObj.objectId); + string result = urn + "," + uploadedObj.objectKey; + + return result;//uploadedObj; + } + + public class UploadFile + { + public string bucketKey { get; set; } + public IFormFile fileToUpload { get; set; } + } + + /// + /// Base64 enconde a string + /// + public static string Base64Encode(string plainText) + { + var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); + return System.Convert.ToBase64String(plainTextBytes); + } + } +} \ No newline at end of file diff --git a/Backend/Controllers/UserInfoController.cs b/Backend/Controllers/UserInfoController.cs index 9fe8c7b..70de7b2 100644 --- a/Backend/Controllers/UserInfoController.cs +++ b/Backend/Controllers/UserInfoController.cs @@ -173,7 +173,7 @@ namespace Backend.Controllers { "@message_content", sendContent} }; - await backendRepository.AddOneByCustomTable(insertNotify, "background_service_message_notification_task"); + //await backendRepository.AddOneByCustomTable(insertNotify, "background_service_message_notification_task"); apiResult.Code = "0000"; apiResult.Msg = "儲存成功"; diff --git a/Backend/Models/BuildModel.cs b/Backend/Models/BuildModel.cs index 4e1fa3e..8c3784d 100644 --- a/Backend/Models/BuildModel.cs +++ b/Backend/Models/BuildModel.cs @@ -20,6 +20,7 @@ namespace Backend.Models public string orgName_3D { get; set; } public string saveName_3D { get; set; } public string extName_3D { get; set; } + public string urn_3D { get; set; } //public string Created_at { get; set; } //建立時間 } diff --git a/Backend/Properties/launchSettings.json b/Backend/Properties/launchSettings.json index 0cf5fad..5fb22ee 100644 --- a/Backend/Properties/launchSettings.json +++ b/Backend/Properties/launchSettings.json @@ -13,7 +13,10 @@ "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", - "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" + "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation", + "FORGE_CALLBACK_URL": "http://localhost:3000/api/forge/callback/oauth", + "FORGE_CLIENT_ID": "TA3hqsFfzQbNOUXKpldKUKSew4SJ21w5", + "FORGE_CLIENT_SECRET": "D002f92d839144f8" } }, "Backend": { diff --git a/Backend/Views/BuildInfo/Index.cshtml b/Backend/Views/BuildInfo/Index.cshtml index 3ed27d0..8770485 100644 --- a/Backend/Views/BuildInfo/Index.cshtml +++ b/Backend/Views/BuildInfo/Index.cshtml @@ -45,6 +45,7 @@ var selected_build_guid_top = ""; var selected_build_guid_top_name; var selected_floor_guid = ""; + let input3Dfile = null; //#region 區域基本資料 document ready $(function () { @@ -261,121 +262,367 @@ maxlength: 50, filterspace: true }, - file_3d_modal: { - accept: "image/svg+xml" + build_file_3d_modal: { + required: true, extension: "nwc|nwd" } - } + }, + messages: { build_file_3d_modal: "File must be nwc, nwd" } }); - //#endregion //#region 儲存區域基本資料 function SaveBuild() { if ($("#build-form").valid()) { $("#save-building-btn").html('').attr("disabled", true); - var url = "/BuildInfo/SaveBuildInfo"; - var formData = new FormData(); - formData.append("building_tag", $('#build_name_tag').val()); - formData.append("Full_name", $('#build_name_modal').val()); - formData.append("Ip_address", $('#ip_address_modal').val()); - formData.append("Ip_port", $('#ip_port_modal').val()); + if(input3Dfile != undefined && input3Dfile != null) {//上傳3d檔案至forge平台 + var file = input3Dfile; + var formData = new FormData(); + formData.append('fileToUpload', file); + formData.append('bucketKey', "ta3hqsffzqbnouxkpldkuksew4sj21w5-bims_models");//forge上傳平台-資料夾 - maps = $('#build_file_3d_modal')[0].files; - if (maps.length > 0) { - var file_names = maps[0].name.split("."); + $.ajax({ + url: '/api/forge/oss/objects', + data: formData, + processData: false, + contentType: false, + type: 'POST', + success: function (data) { + var datas = data.split(","); + var urn = datas[0]; + let m3d_names = datas[1].split("."); - formData.append("Map3dFile", maps[0]); - formData.append("orgName_3D", file_names[0]); - formData.append("extName_3D", file_names[1]); + var url = "/BuildInfo/SaveBuildInfo"; + + var formData2 = new FormData(); + formData2.append("building_tag", $('#build_name_tag').val()); + formData2.append("Full_name", $('#build_name_modal').val()); + formData2.append("Ip_address", $('#ip_address_modal').val()); + formData2.append("Ip_port", $('#ip_port_modal').val()); + + maps = $('#build_file_3d_modal')[0].files; + if (maps.length > 0) { + var file_names = maps[0].name.split("."); + + formData2.append("Map3dFile", maps[0]); + } + formData2.append("urn_3D", urn); + formData2.append("orgName_3D", m3d_names[0]); + formData2.append("extName_3D", m3d_names[1]); + + $.ajax({ + type: "POST", + url: url, + data: formData2, + cache: false, + contentType: false, + processData: false, + success: function (rel) { + $("#save-building-btn").html('確定').attr("disabled", false); + if (rel.code != "0000") { + if (rel.code == "9999") { + toast_error(rel.msg); + } + else { + toast_warning(rel.msg); + } + return; + } + else { + toast_ok(rel.msg); + buildInfoTable.ajax.reload(null, false); + $('#build-modal').modal('hide'); + return; + } + }, + fail: function (xhr, status, error) { + $("#save-building-btn").html('確定').attr("disabled", false); + } + }); + + }, + fail: function (xhr, status, error) { + toast_error("上傳3d模型檔失敗!"); + $("#save-building-btn").html('確定').attr("disabled", false); + } + }); } + else { + toast_warning("無3d模型檔案!"); + var url = "/BuildInfo/SaveBuildInfo"; - $.ajax({ - type: "POST", - url: url, - data: formData, - cache: false, - contentType: false, - processData: false, - success: function (rel) { - $("#save-building-btn").html('確定').attr("disabled", false); - if (rel.code != "0000") { - if (rel.code == "9999") { - toast_error(rel.msg); + var formData = new FormData(); + formData.append("building_tag", $('#build_name_tag').val()); + formData.append("Full_name", $('#build_name_modal').val()); + formData.append("Ip_address", $('#ip_address_modal').val()); + formData.append("Ip_port", $('#ip_port_modal').val()); + + maps = $('#build_file_3d_modal')[0].files; + if (maps.length > 0) { + var file_names = maps[0].name.split("."); + + formData.append("Map3dFile", maps[0]); + formData.append("orgName_3D", file_names[0]); + formData.append("extName_3D", file_names[1]); + } + + $.ajax({ + type: "POST", + url: url, + data: formData, + cache: false, + contentType: false, + processData: false, + success: function (rel) { + $("#save-building-btn").html('確定').attr("disabled", false); + if (rel.code != "0000") { + if (rel.code == "9999") { + toast_error(rel.msg); + } + else { + toast_warning(rel.msg); + } + return; } else { - toast_warning(rel.msg); + toast_ok(rel.msg); + buildInfoTable.ajax.reload(null, false); + $('#build-modal').modal('hide'); + return; } - return; + }, + fail: function (xhr, status, error) { + $("#save-building-btn").html('確定').attr("disabled", false); } - else { - toast_ok(rel.msg); - buildInfoTable.ajax.reload(null, false); - $('#build-modal').modal('hide'); - return; - } - }, - fail: function (xhr, status, error) { - $("#save-building-btn").html('確定').attr("disabled", false); - } - }); + }); + } + + //var url = "/BuildInfo/SaveBuildInfo"; + + //var formData = new FormData(); + //formData.append("building_tag", $('#build_name_tag').val()); + //formData.append("Full_name", $('#build_name_modal').val()); + //formData.append("Ip_address", $('#ip_address_modal').val()); + //formData.append("Ip_port", $('#ip_port_modal').val()); + + //maps = $('#build_file_3d_modal')[0].files; + //if (maps.length > 0) { + // var file_names = maps[0].name.split("."); + + // formData.append("Map3dFile", maps[0]); + // formData.append("orgName_3D", file_names[0]); + // formData.append("extName_3D", file_names[1]); + //} + + //$.ajax({ + // type: "POST", + // url: url, + // data: formData, + // cache: false, + // contentType: false, + // processData: false, + // success: function (rel) { + // $("#save-building-btn").html('確定').attr("disabled", false); + // if (rel.code != "0000") { + // if (rel.code == "9999") { + // toast_error(rel.msg); + // } + // else { + // toast_warning(rel.msg); + // } + // return; + // } + // else { + // toast_ok(rel.msg); + // buildInfoTable.ajax.reload(null, false); + // $('#build-modal').modal('hide'); + // return; + // } + // }, + // fail: function (xhr, status, error) { + // $("#save-building-btn").html('確定').attr("disabled", false); + // } + //}); + } } function EditBuild() { if ($("#build-form").valid()) { $("#save-building-btn").html('').attr("disabled", true); - var url = "/BuildInfo/EditBuildInfo"; - var formData = new FormData(); + if (input3Dfile != undefined && input3Dfile != null) {//上傳3d檔案至forge平台 + var file = input3Dfile; + var formData = new FormData(); + formData.append('fileToUpload', file); + formData.append('bucketKey', "ta3hqsffzqbnouxkpldkuksew4sj21w5-bims_models");//forge上傳平台-資料夾 - formData.append("building_tag", selected_build_guid); - formData.append("Full_name", $('#build_name_modal').val()); - formData.append("Ip_address", $('#ip_address_modal').val()); - formData.append("Ip_port", $('#ip_port_modal').val()); + $.ajax({ + url: '/api/forge/oss/objects', + data: formData, + processData: false, + contentType: false, + type: 'POST', + success: function (data) { + var datas = data.split(","); + var urn = datas[0]; + let m3d_names = datas[1].split("."); - maps = $('#build_file_3d_modal')[0].files; - if (maps.length > 0) { - var file_names = maps[0].name.split("."); + var url = "/BuildInfo/EditBuildInfo"; + var formData2 = new FormData(); - formData.append("Map3dFile", maps[0]); - formData.append("orgName_3D", file_names[0]); - formData.append("extName_3D", file_names[1]); + formData2.append("building_tag", selected_build_guid); + formData2.append("Full_name", $('#build_name_modal').val()); + formData2.append("Ip_address", $('#ip_address_modal').val()); + formData2.append("Ip_port", $('#ip_port_modal').val()); + + maps = $('#build_file_3d_modal')[0].files; + if (maps.length > 0) { + var file_names = maps[0].name.split("."); + + formData2.append("Map3dFile", maps[0]); + //formData2.append("orgName_3D", file_names[0]); + //formData2.append("extName_3D", file_names[1]); + } + formData2.append("urn_3D", urn); + formData2.append("orgName_3D", m3d_names[0]); + formData2.append("extName_3D", m3d_names[1]); + + $.ajax({ + type: "POST", + url: url, + data: formData2, + cache: false, + contentType: false, + processData: false, + success: function (rel) { + $("#save-building-btn").html('確定').attr("disabled", false); + if (rel.code != "0000") { + if (rel.code == "9999") { + toast_error(rel.msg); + } + else { + toast_warning(rel.msg); + } + return; + } + else { + toast_ok(rel.msg); + buildInfoTable.ajax.reload(null, false); + $('#build-modal').modal('hide'); + return; + } + }, + fail: function (xhr, status, error) { + $("#save-building-btn").html('確定').attr("disabled", false); + } + }); + + }, + fail: function (xhr, status, error) { + toast_error("上傳3d模型檔失敗!"); + $("#save-building-btn").html('確定').attr("disabled", false); + } + }); } + else { + var url = "/BuildInfo/EditBuildInfo"; + var formData = new FormData(); - $.ajax({ - type: "POST", - url: url, - data: formData, - cache: false, - contentType: false, - processData: false, - success: function (rel) { - $("#save-building-btn").html('確定').attr("disabled", false); - if (rel.code != "0000") { - if (rel.code == "9999") { - toast_error(rel.msg); + formData.append("building_tag", selected_build_guid); + formData.append("Full_name", $('#build_name_modal').val()); + formData.append("Ip_address", $('#ip_address_modal').val()); + formData.append("Ip_port", $('#ip_port_modal').val()); + + maps = $('#build_file_3d_modal')[0].files; + if (maps.length > 0) { + var file_names = maps[0].name.split("."); + + formData.append("Map3dFile", maps[0]); + formData.append("orgName_3D", file_names[0]); + formData.append("extName_3D", file_names[1]); + } + + $.ajax({ + type: "POST", + url: url, + data: formData, + cache: false, + contentType: false, + processData: false, + success: function (rel) { + $("#save-building-btn").html('確定').attr("disabled", false); + if (rel.code != "0000") { + if (rel.code == "9999") { + toast_error(rel.msg); + } + else { + toast_warning(rel.msg); + } + return; } else { - toast_warning(rel.msg); + toast_ok(rel.msg); + buildInfoTable.ajax.reload(null, false); + $('#build-modal').modal('hide'); + return; } - return; + }, + fail: function (xhr, status, error) { + $("#save-building-btn").html('確定').attr("disabled", false); } - else { - toast_ok(rel.msg); - buildInfoTable.ajax.reload(null, false); - $('#build-modal').modal('hide'); - return; - } - }, - fail: function (xhr, status, error) { - $("#save-building-btn").html('確定').attr("disabled", false); - } - }); + }); + } + + //var url = "/BuildInfo/EditBuildInfo"; + //var formData = new FormData(); + + //formData.append("building_tag", selected_build_guid); + //formData.append("Full_name", $('#build_name_modal').val()); + //formData.append("Ip_address", $('#ip_address_modal').val()); + //formData.append("Ip_port", $('#ip_port_modal').val()); + + //maps = $('#build_file_3d_modal')[0].files; + //if (maps.length > 0) { + // var file_names = maps[0].name.split("."); + + // formData.append("Map3dFile", maps[0]); + // formData.append("orgName_3D", file_names[0]); + // formData.append("extName_3D", file_names[1]); + //} + + //$.ajax({ + // type: "POST", + // url: url, + // data: formData, + // cache: false, + // contentType: false, + // processData: false, + // success: function (rel) { + // $("#save-building-btn").html('確定').attr("disabled", false); + // if (rel.code != "0000") { + // if (rel.code == "9999") { + // toast_error(rel.msg); + // } + // else { + // toast_warning(rel.msg); + // } + // return; + // } + // else { + // toast_ok(rel.msg); + // buildInfoTable.ajax.reload(null, false); + // $('#build-modal').modal('hide'); + // return; + // } + // }, + // fail: function (xhr, status, error) { + // $("#save-building-btn").html('確定').attr("disabled", false); + // } + //}); } } //#endregion - - } \ No newline at end of file diff --git a/Backend/Views/BuildInfo/_BuildInfo.cshtml b/Backend/Views/BuildInfo/_BuildInfo.cshtml index 231c234..2ec7661 100644 --- a/Backend/Views/BuildInfo/_BuildInfo.cshtml +++ b/Backend/Views/BuildInfo/_BuildInfo.cshtml @@ -57,8 +57,8 @@
- - + +
diff --git a/Backend/wwwroot/upload/build_map/0e41ff07-7aee-4d69-86f4-608171657bc4.nwd b/Backend/wwwroot/upload/build_map/0e41ff07-7aee-4d69-86f4-608171657bc4.nwd new file mode 100644 index 0000000..dd9b1c0 Binary files /dev/null and b/Backend/wwwroot/upload/build_map/0e41ff07-7aee-4d69-86f4-608171657bc4.nwd differ diff --git a/Backend/wwwroot/upload/build_map/65494fa9-8418-4d99-9935-c8eef7b3d461.nwc b/Backend/wwwroot/upload/build_map/65494fa9-8418-4d99-9935-c8eef7b3d461.nwc new file mode 100644 index 0000000..df46449 Binary files /dev/null and b/Backend/wwwroot/upload/build_map/65494fa9-8418-4d99-9935-c8eef7b3d461.nwc differ diff --git a/Frontend/_dashboard.html b/Frontend/_dashboard.html index cc0e539..b521f52 100644 --- a/Frontend/_dashboard.html +++ b/Frontend/_dashboard.html @@ -158,7 +158,7 @@
- +
@@ -705,4 +705,12 @@ }); + function goElectricMeter() { + pageAct.sysMainTag = $('#subSysBtnE4').data("subSysObj").main_system_tag; + pageAct.sysSubTag = $('#subSysBtnE4').data("subSysObj").sub_system_tag; + pageAct.sysSubName = $('#subSysBtnE4').data("subSysObj").full_name; + pageAct.sysSubObj = $('#subSysBtnE4').data("subSysObj"); + $("#js-page-content").load("_sysMonAll.html", loadCallback); + } + \ No newline at end of file diff --git a/Frontend/_sysElevator.html b/Frontend/_sysElevator.html index 5490cad..c45699f 100644 --- a/Frontend/_sysElevator.html +++ b/Frontend/_sysElevator.html @@ -1,9 +1,11 @@
@@ -35,19 +51,21 @@
- -
-
-
+
+
-
- +
+
@@ -481,7 +499,7 @@