diff --git a/FrontendWebApi/ApiControllers/HistoryController.cs b/FrontendWebApi/ApiControllers/HistoryController.cs index a4d7476..4bd6377 100644 --- a/FrontendWebApi/ApiControllers/HistoryController.cs +++ b/FrontendWebApi/ApiControllers/HistoryController.cs @@ -14,6 +14,8 @@ using System.Net; using System.Text; using System.Threading.Tasks; using System.Xml; +using NPOI.XSSF.UserModel; +using NPOI.SS.UserModel; namespace FrontendWebApi.ApiControllers { @@ -32,6 +34,117 @@ namespace FrontendWebApi.ApiControllers this.frontendRepository = frontendRepository; } + /// + /// 匯出excel + /// + /// + /// + public FileResult OpeExportExcel([FromBody] List lhe) + { + var workbook = new XSSFWorkbook(); + #region excel設定 + IFont font12 = workbook.CreateFont(); + font12.FontName = "新細明體"; + font12.FontHeightInPoints = 12; + ICellStyle style12 = workbook.CreateCellStyle(); + style12.SetFont(font12); + style12.Alignment = HorizontalAlignment.Center; + style12.VerticalAlignment = VerticalAlignment.Center; + IFont font12Times = workbook.CreateFont(); + font12Times.FontName = "Times New Roman"; + font12Times.FontHeightInPoints = 12; + IFont font18 = workbook.CreateFont(); + font18.FontName = "新細明體"; + font18.FontHeightInPoints = 18; + font18.IsBold = true; + ICellStyle styleTitle18 = workbook.CreateCellStyle(); + styleTitle18.SetFont(font18); + styleTitle18.Alignment = HorizontalAlignment.Center; + styleTitle18.VerticalAlignment = VerticalAlignment.Center; + ICellStyle styleLeft12 = workbook.CreateCellStyle(); + styleLeft12.SetFont(font12); + styleLeft12.Alignment = HorizontalAlignment.Left; + styleLeft12.VerticalAlignment = VerticalAlignment.Center; + ICellStyle styleLine12 = workbook.CreateCellStyle(); + styleLine12.SetFont(font12); + styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; + styleLine12.VerticalAlignment = VerticalAlignment.Center; + styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; + styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; + styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; + styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; + ICellStyle stylein12 = workbook.CreateCellStyle(); + stylein12.SetFont(font12Times); + stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left; + stylein12.VerticalAlignment = VerticalAlignment.Center; + stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; + stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; + stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; + stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; + stylein12.WrapText = true; + #endregion + + var sheet = workbook.CreateSheet("歷史資料"); + int RowPosition = 0; + #region set cell + IRow row = sheet.CreateRow(RowPosition); + sheet.SetColumnWidth(0, 4 * 160 * 12); + sheet.SetColumnWidth(1, 4 * 160 * 12); + sheet.SetColumnWidth(2, 4 * 160 * 12); + sheet.SetColumnWidth(3, 4 * 160 * 12); + sheet.SetColumnWidth(4, 4 * 160 * 12); + sheet.SetColumnWidth(5, 4 * 160 * 12); + sheet.SetColumnWidth(6, 4 * 160 * 12); + sheet.SetColumnWidth(7, 4 * 160 * 12); + ICell cell = row.CreateCell(0); + cell.SetCellValue("設備名稱"); + cell.CellStyle = styleLine12; + cell = row.CreateCell(1); + cell.SetCellValue("數值"); + cell.CellStyle = styleLine12; + cell = row.CreateCell(2); + cell.SetCellValue("記錄時間"); + cell.CellStyle = styleLine12; + #endregion + + if (lhe.Count > 0) + { + foreach (var he in lhe) + { + RowPosition += 1; + row = sheet.CreateRow(RowPosition); + for (var i = 0; i < 3; i++) + { + cell = row.CreateCell(i); + if (i == 0) + { + cell.SetCellValue(he.device_name); + } + if (i == 1) + { + cell.SetCellValue(he.value); + } + if (i == 2) + { + cell.SetCellValue(he.record_time); + } + + cell.CellStyle = style12; + } + } + } + + var ms = new NpoiMemoryStream + { + AllowClose = false + }; + workbook.Write(ms); + ms.Flush(); + ms.Seek(0, SeekOrigin.Begin); + + return File(ms, "application/vnd.ms-excel", "廠商資料.xlsx"); + } + /// /// 即時趨勢條件過濾條件面板 /// @@ -39,7 +152,7 @@ namespace FrontendWebApi.ApiControllers /// [HttpPost] [Route("api/History/GetMainSub")] - public async Task>> GetMainSub(string account) + public async Task>> GetMainSub() { ApiResult apiResult = new ApiResult(jwt_str); if (!jwtlife) @@ -50,38 +163,37 @@ namespace FrontendWebApi.ApiControllers try { var dbsub = await frontendRepository.GetAllAsync( - @$"select distinct e.full_name main_name,e.main_system_guid main_system_guid,d.full_name sub_name,d.sub_system_guid sub_system_guid, e.priority, d.priority from role_auth a + @$"select distinct e.full_name main_name,e.device_system_tag main_system_tag,d.full_name sub_name,d.device_name_tag sub_system_tag, e.priority, d.priority from role_auth a join auth_page b on a.AuthCode = b.AuthCode join userinfo c on c.role_guid = a.role_guid - join sub_system d on d.sub_system_guid = b.ShowView - join main_system e on e.main_system_guid = d.main_system_guid - where c.account = '{account}' - order by e.priority, d.priority"); + join variable v2 on d.device_name_tag = v2.system_value and v2.system_type = @sub_system_type + join variable v1 on d.device_system_tag = v1.system_value and v1.system_type = @main_system_type + where c.account = @account + order by e.priority, d.priority", new { @account = myUser.account, @sub_system_type = sub_system_type, @main_system_type = main_system_type }); var dbbuilding = await frontendRepository.GetAllAsync( @$"select distinct d.building_guid,d.full_name,d.priority from role_auth a join auth_page b on a.AuthCode = b.AuthCode join userinfo c on c.role_guid = a.role_guid - join building d on d.building_guid = b.building_guid - where c.account = '{account}' + join building d on d.device_building_tag = b.building_tag + where c.account = '{myUser.account}' order by d.priority - " - ); - var mains = dbsub.GroupBy(a => a.main_system_guid).ToList(); + ", new { @account = myUser.account }); + var mains = dbsub.GroupBy(a => a.main_system_tag).ToList(); apiResult.Data = new History_MainSubBuildFloor(); apiResult.Data.history_Main_Systems = new List(); foreach (var main in mains) { History_Main_system history_Main_System = new History_Main_system(); - history_Main_System.main_system_guid = main.Select(a => a.main_system_guid).FirstOrDefault(); + history_Main_System.main_system_tag = main.Select(a => a.main_system_tag).FirstOrDefault(); history_Main_System.full_name = main.Select(a => a.main_name).FirstOrDefault(); history_Main_System.History_Sub_systems = new List(); - var subs = main.GroupBy(a => a.sub_system_guid).ToList(); + var subs = main.GroupBy(a => a.main_system_tag).ToList(); foreach (var sub in subs) { History_Sub_system history_Sub_System = new History_Sub_system(); history_Sub_System.full_name = sub.Select(a => a.sub_name).FirstOrDefault(); - history_Sub_System.sub_system_guid = sub.Select(a => a.sub_system_guid).FirstOrDefault(); + history_Sub_System.sub_system_tag = sub.Select(a => a.sub_system_tag).FirstOrDefault(); history_Main_System.History_Sub_systems.Add(history_Sub_System); } apiResult.Data.history_Main_Systems.Add(history_Main_System); @@ -662,7 +774,7 @@ namespace FrontendWebApi.ApiControllers var mainSubSystemRawDatas = await frontendRepository.GetAllAsync(sqlMainSubSystem, post); - var mainSubSystemRawDatas_GroupBy_main_system_guid = mainSubSystemRawDatas.GroupBy(x => x.main_system_guid).ToList(); + var mainSubSystemRawDatas_GroupBy_main_system_guid = mainSubSystemRawDatas.GroupBy(x => x.main_system_tag).ToList(); List history_Main_Systems = new List(); foreach (var mainSubSystemRawData in mainSubSystemRawDatas_GroupBy_main_system_guid) @@ -672,7 +784,7 @@ namespace FrontendWebApi.ApiControllers { History_Sub_system history_Sub_System = new History_Sub_system() { - sub_system_guid = SubSystemRawData.sub_system_guid, + sub_system_tag = SubSystemRawData.sub_system_tag, full_name = SubSystemRawData.sub_name, }; @@ -681,7 +793,7 @@ namespace FrontendWebApi.ApiControllers History_Main_system history_Main_System = new History_Main_system() { - main_system_guid = mainSubSystemRawData.Key, + main_system_tag = mainSubSystemRawData.Key, full_name = mainSubSystemRawData.First().main_name, History_Sub_systems = history_Sub_Systems }; diff --git a/FrontendWebApi/ApiControllers/ModelDerivativeController.cs b/FrontendWebApi/ApiControllers/ModelDerivativeController.cs new file mode 100644 index 0000000..dc32d77 --- /dev/null +++ b/FrontendWebApi/ApiControllers/ModelDerivativeController.cs @@ -0,0 +1,55 @@ +using Autodesk.Forge.Model; +using Autodesk.Forge; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace FrontendWebApi.ApiControllers +{ + public class ModelDerivativeController : ControllerBase //MyBaseApiController//Controller + { + /// + /// 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/FrontendWebApi/ApiControllers/OAuthController.cs b/FrontendWebApi/ApiControllers/OAuthController.cs new file mode 100644 index 0000000..61b7f1f --- /dev/null +++ b/FrontendWebApi/ApiControllers/OAuthController.cs @@ -0,0 +1,67 @@ +using Autodesk.Forge; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using System; + +namespace FrontendWebApi.ApiControllers +{ + public class OAuthController : ControllerBase //MyBaseApiController//Controller + { + + + 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( + "TA3hqsFfzQbNOUXKpldKUKSew4SJ21w5", + "D002f92d839144f8", + grantType, + scopes); + return bearer; + } + + /// + /// Reads appsettings from web.config + /// + public static string GetAppSetting(string settingKey) + { + return Environment.GetEnvironmentVariable(settingKey).Trim(); + } + } +} diff --git a/FrontendWebApi/ApiControllers/OSSController.cs b/FrontendWebApi/ApiControllers/OSSController.cs new file mode 100644 index 0000000..0dc1458 --- /dev/null +++ b/FrontendWebApi/ApiControllers/OSSController.cs @@ -0,0 +1,148 @@ +using Autodesk.Forge.Model; +using Autodesk.Forge; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using System.IO; + +namespace FrontendWebApi.ApiControllers +{ + public class OSSController : ControllerBase //MyBaseApiController//Controller + { + private IWebHostEnvironment _env; + public OSSController(IWebHostEnvironment env) { _env = env; } + string id = "TA3hqsFfzQbNOUXKpldKUKSew4SJ21w5"; + public string ClientId { get { return 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); + + return 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); + } + } +} diff --git a/FrontendWebApi/Models/HistoryClass.cs b/FrontendWebApi/Models/HistoryClass.cs index c583271..4da37de 100644 --- a/FrontendWebApi/Models/HistoryClass.cs +++ b/FrontendWebApi/Models/HistoryClass.cs @@ -55,9 +55,9 @@ namespace FrontendWebApi.Models // } public class HistoryDBMainSub { - public string main_system_guid { get; set; } + public string main_system_tag { get; set; } public string main_name { get; set; } - public string sub_system_guid { get; set; } + public string sub_system_tag { get; set; } public string sub_name { get; set; } } @@ -88,13 +88,13 @@ namespace FrontendWebApi.Models } public class History_Main_system { - public string main_system_guid { get; set; } + public string main_system_tag { get; set; } public string full_name { get; set; } public List History_Sub_systems { get; set; } } public class History_Sub_system { - public string sub_system_guid { get; set; } + public string sub_system_tag { get; set; } public string full_name { get; set; } } public class History_PostDevice @@ -233,4 +233,10 @@ namespace FrontendWebApi.Models public string Timestamp { get; set; } } + public class HistoryExport + { + public string device_name { get; set; } + public string value { get; set; } + public string record_time { get; set; } + } } diff --git a/FrontendWebApi/Properties/launchSettings.json b/FrontendWebApi/Properties/launchSettings.json index 5c10218..7d29894 100644 --- a/FrontendWebApi/Properties/launchSettings.json +++ b/FrontendWebApi/Properties/launchSettings.json @@ -1,13 +1,4 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:3604", - "sslPort": 0 - } - }, - "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { "IIS Express": { "commandName": "IISExpress", @@ -22,9 +13,22 @@ "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", + "ASPNETCORE_URLS": "http://localhost:5500" }, "applicationUrl": "https://localhost:5001;http://localhost:5000" } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:3604", + "sslPort": 0 + } } } \ No newline at end of file