Merge branch 'master' of https://gitea.mjm-staging.developers-homelab.net/BIMS/BIMS
This commit is contained in:
		
						commit
						0aea9d189a
					
				@ -18,6 +18,7 @@
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Autodesk.Forge" Version="1.9.7" />
 | 
			
		||||
    <PackageReference Include="iTextSharp" Version="5.5.13.2" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.21" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.20" />
 | 
			
		||||
 | 
			
		||||
@ -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<string, object> building = new Dictionary<string, object>();
 | 
			
		||||
                    building = new Dictionary<string, object>()
 | 
			
		||||
                    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<string, object> building = new Dictionary<string, object>();
 | 
			
		||||
                        building = new Dictionary<string, object>()
 | 
			
		||||
                        {
 | 
			
		||||
                            { "@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<string, object> building = new Dictionary<string, object>();
 | 
			
		||||
                        building = new Dictionary<string, object>()
 | 
			
		||||
                        {
 | 
			
		||||
                            { "@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<string, object> building = new Dictionary<string, object>();
 | 
			
		||||
                    building = new Dictionary<string, object>()
 | 
			
		||||
                    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<string, object> building = new Dictionary<string, object>();
 | 
			
		||||
                        building = new Dictionary<string, object>()
 | 
			
		||||
                        {
 | 
			
		||||
                            { "@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<string, object> building = new Dictionary<string, object>();
 | 
			
		||||
                        building = new Dictionary<string, object>()
 | 
			
		||||
                        {
 | 
			
		||||
                            { "@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)
 | 
			
		||||
                    {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										53
									
								
								Backend/Controllers/ModelDerivativeController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Backend/Controllers/ModelDerivativeController.cs
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Start the translation job for a give bucketKey/objectName
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="objModel"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/forge/modelderivative/jobs")]
 | 
			
		||||
        public async Task<dynamic> TranslateObject([FromBody] TranslateObjectModel objModel)
 | 
			
		||||
        {
 | 
			
		||||
            dynamic oauth = await OAuthController.GetInternalAsync();
 | 
			
		||||
 | 
			
		||||
            // prepare the payload
 | 
			
		||||
            List<JobPayloadItem> outputs = new List<JobPayloadItem>()
 | 
			
		||||
            {
 | 
			
		||||
            new JobPayloadItem(
 | 
			
		||||
                JobPayloadItem.TypeEnum.Svf,
 | 
			
		||||
                new List<JobPayloadItem.ViewsEnum>()
 | 
			
		||||
                {
 | 
			
		||||
                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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Model for TranslateObject method
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public class TranslateObjectModel
 | 
			
		||||
        {
 | 
			
		||||
            public string bucketKey { get; set; }
 | 
			
		||||
            public string objectName { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								Backend/Controllers/OAuthController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								Backend/Controllers/OAuthController.cs
									
									
									
									
									
										Normal file
									
								
							@ -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; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get access token with public (viewables:read) scope
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("api/forge/oauth/token")]
 | 
			
		||||
        public async Task<dynamic> 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get access token with internal (write) scope
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static async Task<dynamic> 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get the access token from Autodesk
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private static async Task<dynamic> 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Reads appsettings from web.config
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string GetAppSetting(string settingKey)
 | 
			
		||||
        {
 | 
			
		||||
            return Environment.GetEnvironmentVariable(settingKey).Trim();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										150
									
								
								Backend/Controllers/OSSController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								Backend/Controllers/OSSController.cs
									
									
									
									
									
										Normal file
									
								
							@ -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(); } }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Return list of buckets (id=#) or list of objects (id=bucketKey)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("api/forge/oss/buckets")]
 | 
			
		||||
        public async Task<IList<TreeNode>> GetOSSAsync(string id)
 | 
			
		||||
        {
 | 
			
		||||
            IList<TreeNode> nodes = new List<TreeNode>();
 | 
			
		||||
            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<string, dynamic> 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<string, dynamic> objInfo in new DynamicDictionaryItems(objectsList.items))
 | 
			
		||||
                {
 | 
			
		||||
                    nodes.Add(new TreeNode(Base64Encode((string)objInfo.Value.objectId),
 | 
			
		||||
                      objInfo.Value.objectKey, "object", false));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return nodes;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Model data for jsTree used on GetOSSAsync
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        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; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Create a new bucket 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/forge/oss/buckets")]
 | 
			
		||||
        public async Task<dynamic> 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");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Input model for CreateBucket method
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public class CreateBucketModel
 | 
			
		||||
        {
 | 
			
		||||
            public string bucketKey { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Receive a file from the client and upload to the bucket
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/forge/oss/objects")]
 | 
			
		||||
        public async Task<string> 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; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Base64 enconde a string
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string Base64Encode(string plainText)
 | 
			
		||||
        {
 | 
			
		||||
            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
 | 
			
		||||
            return System.Convert.ToBase64String(plainTextBytes);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -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 = "儲存成功";
 | 
			
		||||
 | 
			
		||||
@ -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; }  //建立時間
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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": {
 | 
			
		||||
 | 
			
		||||
@ -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('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').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('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').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
 | 
			
		||||
 | 
			
		||||
    </script>
 | 
			
		||||
    <script>
 | 
			
		||||
    
 | 
			
		||||
        //#region 樓層設定 document ready
 | 
			
		||||
        $(function () {
 | 
			
		||||
 | 
			
		||||
@ -701,10 +948,13 @@
 | 
			
		||||
        }
 | 
			
		||||
        //#endregion
 | 
			
		||||
 | 
			
		||||
        //#region 變更樓層平面圖
 | 
			
		||||
        //#region 變更樓層平面圖 3d模型
 | 
			
		||||
        function changeImage(input) {
 | 
			
		||||
            $(`#map_file_preview_modal`).attr("data-src", window.URL.createObjectURL(input.files[0]));
 | 
			
		||||
            input3Dfile = input.files[0];
 | 
			
		||||
        }
 | 
			
		||||
        //#endregion
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    </script>
 | 
			
		||||
}
 | 
			
		||||
@ -57,8 +57,8 @@
 | 
			
		||||
                            <input type="text" id="ip_port_modal" class="form-control" name="ip_port_modal">
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="form-group col-12">
 | 
			
		||||
                            <label class="form-label" for="build_file_3d_modal">3D檔(限制SVG格式)</label>
 | 
			
		||||
                            <input type="file" id="build_file_3d_modal" class="form-control" name="build_file_3d_modal" onchange="changeImage(this)" accept="image/svg+xml">
 | 
			
		||||
                            <label class="form-label" for="build_file_3d_modal">3D檔(限制NWD、NWC格式)</label>
 | 
			
		||||
                            <input type="file" id="build_file_3d_modal" class="form-control" name="build_file_3d_modal" onchange="changeImage(this)">
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </form>
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@ -158,7 +158,7 @@
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="btn-group btn-group-lg col-lg-6 mb-4">
 | 
			
		||||
                    <button type="button" class="btn btn-secondary"><i class="fal fa-car-battery fa-2x"></i></button>
 | 
			
		||||
                    <button type="button" class="btn btn-secondary">電錶系統  </button>
 | 
			
		||||
                    <button type="button" class="btn btn-secondary" onclick="goElectricMeter()">電錶系統  </button>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="btn-group btn-group-lg col-lg-6 mb-4">
 | 
			
		||||
                    <button type="button" class="btn btn-secondary"><i class="fal fa-wind fa-2x"></i></button>
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
@ -1,9 +1,11 @@
 | 
			
		||||
<style>
 | 
			
		||||
    .elevator {
 | 
			
		||||
        background-color: #fff;
 | 
			
		||||
        height: 520px;
 | 
			
		||||
        min-height: 520px;
 | 
			
		||||
    }
 | 
			
		||||
    .elevator-table-wrapper {
 | 
			
		||||
        padding:0.8rem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    table.elevator-build {
 | 
			
		||||
        /*border: 1px double #000;*/
 | 
			
		||||
    }
 | 
			
		||||
@ -25,6 +27,20 @@
 | 
			
		||||
        height: 47px;
 | 
			
		||||
        border: 4px solid orange;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .elevator-item-toup {
 | 
			
		||||
        border: 4px solid rgba(255,255,255,0);
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        border-bottom: 0;
 | 
			
		||||
        z-index: 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .elevator-item-todown {
 | 
			
		||||
        border: 4px solid rgba(255,255,255,0);
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        border-top: 0;
 | 
			
		||||
        z-index: 2;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<div class="d-flex">
 | 
			
		||||
@ -35,19 +51,21 @@
 | 
			
		||||
            <div id="elevatorBlock" class="elevator">
 | 
			
		||||
                <div class="elevator-header">
 | 
			
		||||
                    <div class="row m-0 align-items-center p-2 gap-3 btn-group btn-group-toggle">
 | 
			
		||||
                        <button class="btn btn-secondary btn-sm active" data-tabname="floShowType" data-target="#2dDiv">2D
 | 
			
		||||
                        <button class="btn btn-secondary btn-sm" data-tabname="floShowType" data-target="#2dDiv">
 | 
			
		||||
                            2D
 | 
			
		||||
                        </button>
 | 
			
		||||
                        <button class="btn btn-secondary btn-sm" data-tabname="floShowType" data-target="#3dDiv">3D
 | 
			
		||||
                        <button class="btn btn-secondary btn-sm active" data-tabname="floShowType" data-target="#3dDiv" onclick="show3D()">
 | 
			
		||||
                            3D
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="elevator-body d-flex align-items-center justify-content-center yt-table-container">
 | 
			
		||||
                    <div id="2dDiv" data-tabname="floShowType" data-tabrole="child">
 | 
			
		||||
                <div class="elevator-body d-flex align-items-center justify-content-center">
 | 
			
		||||
                    <div id="2dDiv" class="p-2" data-tabname="floShowType" data-tabrole="child">
 | 
			
		||||
                        <table id="floorTable" class="elevator-build m-auto">
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div id="3dDiv" data-tabname="floShowType" data-tabrole="child">
 | 
			
		||||
 | 
			
		||||
                    <div id="3dDiv" class="w-100" data-tabname="floShowType" data-tabrole="child">
 | 
			
		||||
                        <div id="forgeViewer"></div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
@ -481,7 +499,7 @@
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div id="detDevDiv" style="display:none">
 | 
			
		||||
                        <button class="btn btn-info" data-toggle="prevDiv"><i class="fas fa-angle-left mr-2"></i>上一頁</button>
 | 
			
		||||
                        <table class="table table-hover">
 | 
			
		||||
                        <table id="eleManDevTable" class="table table-hover">
 | 
			
		||||
                            <thead>
 | 
			
		||||
                                <tr class="text-center">
 | 
			
		||||
                                    <th scope="col">號機</th>
 | 
			
		||||
@ -502,7 +520,7 @@
 | 
			
		||||
                                    <td>
 | 
			
		||||
                                        <div class="d-flex justify-content-center align-items-center">
 | 
			
		||||
                                            <div class="row mr-2">
 | 
			
		||||
                                                <input name="preMea" type="checkbox" class="toggle" data-toggle="toggle">
 | 
			
		||||
                                                <input name="preMea" type="checkbox" class="toggle" data-toggle="toggle" data-point="SP_DP" >
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                            <i id="preMeaSche" data-point="DP" class="fas fa-calendar-alt fs-1-1 mr-2 cur-poi"></i>
 | 
			
		||||
                                        </div>
 | 
			
		||||
@ -510,7 +528,7 @@
 | 
			
		||||
                                    <td>
 | 
			
		||||
                                        <div class="d-flex justify-content-center align-items-center">
 | 
			
		||||
                                            <div class="row mr-2">
 | 
			
		||||
                                                <input name="stop" type="checkbox" class="toggle" data-toggle="toggle">
 | 
			
		||||
                                                <input name="stop" type="checkbox" class="toggle" data-toggle="toggle" data-point="SP_RCS">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                            <i id="stopSche" data-point="RCS" class="fas fa-calendar-alt fs-1-1 mr-2 cur-poi"></i>
 | 
			
		||||
                                        </div>
 | 
			
		||||
@ -518,7 +536,7 @@
 | 
			
		||||
                                    <td>
 | 
			
		||||
                                        <div class="d-flex justify-content-center align-items-center">
 | 
			
		||||
                                            <div class="row mr-2">
 | 
			
		||||
                                                <input name="onlyOpe" type="checkbox" class="toggle" data-toggle="toggle">
 | 
			
		||||
                                                <input name="onlyOpe" type="checkbox" class="toggle" data-toggle="toggle" data-point="SP_IND">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                            <i id="onlyOpeSche" data-point="IND" class="fas fa-calendar-alt fs-1-1 mr-2 cur-poi"></i>
 | 
			
		||||
                                        </div>
 | 
			
		||||
@ -526,7 +544,7 @@
 | 
			
		||||
                                    <td>
 | 
			
		||||
                                        <div class="d-flex justify-content-center align-items-center">
 | 
			
		||||
                                            <div class="row mr-2">
 | 
			
		||||
                                                <input name="vip" type="checkbox" class="toggle" data-toggle="toggle">
 | 
			
		||||
                                                <input name="vip" type="checkbox" class="toggle" data-toggle="toggle" data-point="SP_VIP">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                            <i id="vipSche" data-point="VIP" class="fas fa-calendar-alt fs-1-1 mr-2 cur-poi"></i>
 | 
			
		||||
                                        </div>
 | 
			
		||||
@ -534,7 +552,7 @@
 | 
			
		||||
                                    <td>
 | 
			
		||||
                                        <div class="d-flex justify-content-center align-items-center">
 | 
			
		||||
                                            <div class="row mr-2">
 | 
			
		||||
                                                <input name="retOpe" type="checkbox" class="toggle" data-toggle="toggle">
 | 
			
		||||
                                                <input name="retOpe" type="checkbox" class="toggle" data-toggle="toggle" data-point="SP_RET">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                            <i id="retOpeSche" data-point="RET" class="fas fa-calendar-alt fs-1-1 mr-2 cur-poi"></i>
 | 
			
		||||
                                        </div>
 | 
			
		||||
@ -876,8 +894,10 @@
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    var eleManTable = null;
 | 
			
		||||
    var allDevList = [];
 | 
			
		||||
    var subSeviceData = [];
 | 
			
		||||
    var allDevList = [];       //每個設備
 | 
			
		||||
    var subSeviceData = [];    //每個設備訂閱點位值
 | 
			
		||||
    var floList = [];          //每個樓層
 | 
			
		||||
    var elevObj = null;        //左側 2D 電梯物件
 | 
			
		||||
    var subOrdPath = {
 | 
			
		||||
        "building_tag": pageAct.buiTag,
 | 
			
		||||
        "system_tag": pageAct.sysMainTag,
 | 
			
		||||
@ -889,13 +909,17 @@
 | 
			
		||||
    var allDeviceRowData = []; //所有設備原始資料
 | 
			
		||||
    var global_emergency_alarm_device_number = [];
 | 
			
		||||
    var zoomToggle = 3;
 | 
			
		||||
    var isFirstLoad3D = true;
 | 
			
		||||
    $(function () {
 | 
			
		||||
        initChart();
 | 
			
		||||
        
 | 
			
		||||
        setBuildFloor();
 | 
			
		||||
        setCards();
 | 
			
		||||
        subDeviceSetStatus();
 | 
			
		||||
        setEleManTable();
 | 
			
		||||
        
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    function getFloDevList() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
@ -936,7 +960,7 @@
 | 
			
		||||
            }
 | 
			
		||||
            //現在樓層
 | 
			
		||||
            if (data.point_name == "CP") {
 | 
			
		||||
                $(`#${matchDevice.device_number}_card [name=curFloor]`).text(data.value + "F");
 | 
			
		||||
                $(`#${matchDevice.device_number}_card [name=curFloor]`).text(data.value);
 | 
			
		||||
            }
 | 
			
		||||
            //往上或往下
 | 
			
		||||
            if (getValueByName("RD") == "UP") {
 | 
			
		||||
@ -969,7 +993,9 @@
 | 
			
		||||
            if (subData) {
 | 
			
		||||
                subData[data.point_name] = data.value;
 | 
			
		||||
            }
 | 
			
		||||
            // 設置燈色、卡片閃爍
 | 
			
		||||
            setLightColor();
 | 
			
		||||
            // Card table 更新
 | 
			
		||||
            subDeviceSetTable(matchDevice.device_number);
 | 
			
		||||
            // 重繪 電梯管理 列表
 | 
			
		||||
            reloadEleManTable(setEleManTabDataFromBaja());
 | 
			
		||||
@ -990,6 +1016,12 @@
 | 
			
		||||
            let main = {};
 | 
			
		||||
            // 匯入 Master 名稱`
 | 
			
		||||
            main.devName = master;
 | 
			
		||||
            let subData = subSeviceData.filter(x => x.device_number.split("_")[5] == master)[0];
 | 
			
		||||
            $.each(Object.keys(subData), (idx3, subKey) => {
 | 
			
		||||
                if (subKey.startsWith("SP_FLS_")) { 
 | 
			
		||||
                    main[subKey] = subData[subKey];
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            main._rowType = "master";
 | 
			
		||||
            result.push(main);
 | 
			
		||||
            // 該 Master 底下的設備
 | 
			
		||||
@ -1008,7 +1040,6 @@
 | 
			
		||||
                result.push(main);
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        console.log("redraw", result)
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1023,16 +1054,28 @@
 | 
			
		||||
 | 
			
		||||
        function creLight(type = "trueText") {
 | 
			
		||||
            let lightType = type == "trueText" ? "bg-success" : "bg-danger";
 | 
			
		||||
            return creEle("span", null, null, null, [lightType, "circle-light"]).outerHtml();
 | 
			
		||||
            
 | 
			
		||||
            return $(creEle("span", null, null, null, [lightType, "circle-light"])).outerHtml();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let masterTag = devNum?.split("_")[5];
 | 
			
		||||
 | 
			
		||||
        let notSerFloors = Object.keys(subData).filter(x => x.startsWith("SP_FLS_") && subData[x] == "trueText").map(x => x?.split("SP_FLS_")[1]);
 | 
			
		||||
        floList = Object.keys(subData).filter(x => x.startsWith("SP_FLS_")).map(x => x?.split("SP_FLS_")[1]);
 | 
			
		||||
 | 
			
		||||
        //左側 2D 電梯物件 樓層資料更新
 | 
			
		||||
        if (elevObj.floors.length != floList.length) {
 | 
			
		||||
            elevObj.floors = floList.map((x, idx) => { return { id: x, name: x, sort: idx + 1 } });
 | 
			
		||||
            elevObj.elevators = allDevList.map((x) => { return { id: x.device_number } });
 | 
			
		||||
            elevObj.curElevFloor[matchDevice.device_number] = subData["CP"];
 | 
			
		||||
            elevObj.redraw();
 | 
			
		||||
        } else {
 | 
			
		||||
            
 | 
			
		||||
            elevObj.setElevFloor(matchDevice.device_number, subData["CP"]);
 | 
			
		||||
        }
 | 
			
		||||
        elevObj.setEleMovStatus(matchDevice.device_number, subData["RD"] == "UP" ? 1 : subData["RD"] == "DOWN" ? 2 : 0);
 | 
			
		||||
        //現在樓層
 | 
			
		||||
        if (subData["CP"]) {
 | 
			
		||||
            $(`#imdStaTable_${devNum} [name=curFloor]`).text(subData["CP"] + "F");
 | 
			
		||||
            $(`#imdStaTable_${devNum} [name=curFloor]`).text(subData["CP"]);
 | 
			
		||||
        }
 | 
			
		||||
        //往上或往下
 | 
			
		||||
        if (subData["RD"] == "UP") {
 | 
			
		||||
@ -1073,11 +1116,20 @@
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                let strHtml = ``;
 | 
			
		||||
                let masterArr = [];
 | 
			
		||||
                let masDiv = "";
 | 
			
		||||
                $.each(res.data, (index, floObj) => {
 | 
			
		||||
                   
 | 
			
		||||
                    $.each(floObj.device_list, (index2, devObj) => {
 | 
			
		||||
                        allDevList.push(devObj);
 | 
			
		||||
                        if (masterArr.indexOf(devObj?.device_number?.split("_")[5]) == -1) {
 | 
			
		||||
                            let master = devObj?.device_number?.split("_")[5];
 | 
			
		||||
                            masDiv = creDiv(["col-12"]);
 | 
			
		||||
                            masDiv.append(creEle("h2", master, null, null))
 | 
			
		||||
                            masterArr.push(master);
 | 
			
		||||
                        }
 | 
			
		||||
                        
 | 
			
		||||
                        strHtml += `<div id="${devObj.device_number}_card" class="card dev-card text-white mx-1 mb-3 col-4 " name="devItem" data-id="${devObj.device_guid}" data-number="${devObj.device_number}" data-name="${devObj.full_name}" style="max-width: 18rem;">
 | 
			
		||||
                        strHtml += `<div id="${devObj.device_number}_card" class="card dev-card text-white mb-3 col-4 " name="devItem" data-id="${devObj.device_guid}" data-number="${devObj.device_number}" data-name="${devObj.full_name}" style="max-width: 18rem;">
 | 
			
		||||
                                        <div type="button" class="card-body">
 | 
			
		||||
                                            <span class="d-flex">
 | 
			
		||||
                                                <h5 class="card-title">號機別 : ${devObj.full_name}</h5>
 | 
			
		||||
@ -1090,10 +1142,10 @@
 | 
			
		||||
                                            </span>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </div>`;
 | 
			
		||||
                        masDiv.append(strHtml)
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                })
 | 
			
		||||
                $("#eleCards").html(strHtml);
 | 
			
		||||
                $("#eleCards").html(masDiv);
 | 
			
		||||
                initPopover();
 | 
			
		||||
                //平面圖載入
 | 
			
		||||
                chartHandler(`${baseImgUrl}/upload/floor_map/${res.data[0].floor_map_name}`);
 | 
			
		||||
@ -1103,26 +1155,12 @@
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    //左側 2D 樓層 Table
 | 
			
		||||
    function setBuildFloor() {
 | 
			
		||||
        let options = {
 | 
			
		||||
            floors: [
 | 
			
		||||
                { name: "B2F", sort: 0 },
 | 
			
		||||
                { name: "B1F", sort: 1 },
 | 
			
		||||
                { name: "1F", sort: 2 },
 | 
			
		||||
                { name: "2F", sort: 3 },
 | 
			
		||||
                { name: "3F", sort: 4 },
 | 
			
		||||
                { name: "4F", sort: 5 },
 | 
			
		||||
                { name: "5F", sort: 6 },
 | 
			
		||||
                { name: "6F", sort: 7 },
 | 
			
		||||
            ],
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let eleObj = new ElevatorHandler("#floorTable", options);
 | 
			
		||||
        elevObj = new ElevatorHandler("#floorTable");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Card 即時狀態
 | 
			
		||||
    function drawStateTabBlo(devNum) {
 | 
			
		||||
        let div = creDiv(["row"]);
 | 
			
		||||
        div.append(creDiv(["col-xl-6"]).append(drawImdStaBlock(devNum)))
 | 
			
		||||
@ -1130,6 +1168,7 @@
 | 
			
		||||
        return div.outerHtml();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Card 即時狀態 - 左側 table
 | 
			
		||||
    function drawImdStaBlock(devNum) {
 | 
			
		||||
        let tabEle = $(`<table id="imdStaTable_${devNum}" class="table table-bordered table-striped text-center m-0">`);
 | 
			
		||||
        let tbody = tabEle.append("<tbody>");
 | 
			
		||||
@ -1184,6 +1223,7 @@
 | 
			
		||||
        return tabEle.outerHtml();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Card 即時狀態 - 右側 table
 | 
			
		||||
    function drawOpeModBlock(devNum) {
 | 
			
		||||
        let tabEle = $(`<table id="opeModTable_${devNum}" class="table table-bordered table-striped text-center m-0">`);
 | 
			
		||||
        let tbody = tabEle.append("<tbody>");
 | 
			
		||||
@ -1221,6 +1261,7 @@
 | 
			
		||||
        return tabEle.outerHtml();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 電梯管理 Modal - 資料更新
 | 
			
		||||
    function reloadEleManTable(datas) {
 | 
			
		||||
 | 
			
		||||
        let tabCols = eleManTable.context[0].aoColumns.map(x => x.data);
 | 
			
		||||
@ -1235,6 +1276,7 @@
 | 
			
		||||
        eleManTable.clear().rows.add(datas).draw();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 電梯管理 Modal - table 初始化
 | 
			
		||||
    function setEleManTable() {
 | 
			
		||||
        let tag = "#eleManTable";
 | 
			
		||||
        let datas = [];
 | 
			
		||||
@ -1271,7 +1313,7 @@
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "title": "休止",
 | 
			
		||||
                "data": "RCS",
 | 
			
		||||
                "data": "SP_RCS",
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "title": "獨立運轉",
 | 
			
		||||
@ -1279,17 +1321,21 @@
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "title": "VIP",
 | 
			
		||||
                "data": "VIP",
 | 
			
		||||
                "data": "SP_VIP",
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "title": "回歸",
 | 
			
		||||
                "data": "RET",
 | 
			
		||||
                "data": "SP_RET",
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "title": "不服務樓層",
 | 
			
		||||
                "data": null,
 | 
			
		||||
                "render": function (data, type, row) {
 | 
			
		||||
                    return Object.keys(row).filter(x => x.startsWith("SP_FLS_") && row[x] == "trueText").map(x => x?.split("SP_FLS_")[1]).join("、");
 | 
			
		||||
                    let result = "";
 | 
			
		||||
                    if (row._rowType == "master") {
 | 
			
		||||
                        result = Object.keys(row).filter(x => x.startsWith("SP_FLS_") && row[x] == "trueText").map(x => x?.split("SP_FLS_")[1]).join("、");
 | 
			
		||||
                    }
 | 
			
		||||
                    return result;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
@ -1310,7 +1356,6 @@
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        eleManTable = new YourTeam.JqDataTables.getTableByStatic(tag, datas, columns, column_defs, null, null, null, null, "tpi");
 | 
			
		||||
        console.log(eleManTable)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 電梯管理 Modal - 設置 Detail 訂閱內容
 | 
			
		||||
@ -1329,7 +1374,7 @@
 | 
			
		||||
 | 
			
		||||
        $("#eleManModal #detDevDiv [name=devName]").text(matchDevice.full_name);
 | 
			
		||||
        $("#eleManModal #detDevDiv [name=status]").text(subData["ST"]);
 | 
			
		||||
        $("#eleManModal #detDevDiv [name=curFloor]").text(subData["CP"] + "F");
 | 
			
		||||
        $("#eleManModal #detDevDiv [name=curFloor]").text(subData["CP"]);
 | 
			
		||||
        $("#eleManModal #detDevDiv [name=preMea]").prop("checked", bajaValToBool(subData["SP_DP"]));  //防疫對策
 | 
			
		||||
        $("#eleManModal #detDevDiv [name=stop]").prop("checked", bajaValToBool(subData["SP_RCS"]));
 | 
			
		||||
        $("#eleManModal #detDevDiv [name=onlyOpe]").prop("checked", bajaValToBool(subData["SP_IND"]));
 | 
			
		||||
@ -1347,6 +1392,7 @@
 | 
			
		||||
 | 
			
		||||
        $("#notSerFloTable").html(setNotSerFloTable(allSerFloors));
 | 
			
		||||
        let notSerFloors = Object.keys(subData).filter(x => x.startsWith("SP_FLS_") && subData[x] == "trueText").map(x => x?.split("SP_FLS_")[1]);
 | 
			
		||||
        
 | 
			
		||||
        $(`[name^=notSerChk]`).prop("checked", false);
 | 
			
		||||
        $.each(notSerFloors, (idx, floor) => {
 | 
			
		||||
            $(`[name=notSerChk${floor}]`).prop("checked", true);
 | 
			
		||||
@ -1370,7 +1416,7 @@
 | 
			
		||||
            datas.push({
 | 
			
		||||
                row: idx,
 | 
			
		||||
                col: 1,
 | 
			
		||||
                data: `<input name="notSerChk${row.text}" type="checkbox" class="toggle" data-toggle="toggle">`,
 | 
			
		||||
                data: `<input name="notSerChk${row.text}" data-point="SP_FLS_${row.id}" type="checkbox" class="toggle" data-toggle="toggle">`,
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        $.each(rows, (index, row) => {
 | 
			
		||||
@ -1402,6 +1448,7 @@
 | 
			
		||||
    onEvent("click", "#eleManTable [id^=eleManDevEdit]", function () {
 | 
			
		||||
        let devNum = $(this).prop("id").split("eleManDevEdit")[1];
 | 
			
		||||
        let scheBtn = ["preMeaSche", "stopSche", "onlyOpeSche", "vipSche", "retOpeSche"];
 | 
			
		||||
        $("#detDevDiv").data("devnum", devNum);
 | 
			
		||||
        $("#bajaSche").html("");
 | 
			
		||||
        // 電梯管理 Modal 切換到 detail 頁面
 | 
			
		||||
        modalTogDiv("#eleManModal", "#tabDiv", "#detDevDiv", "next", function () {
 | 
			
		||||
@ -1423,16 +1470,59 @@
 | 
			
		||||
        let master = $(this).prop("id").split("eleManMasEdit")[1];
 | 
			
		||||
        let subData = subSeviceData.filter(x => x.device_number.split("_")[5] == master)[0];
 | 
			
		||||
        $("#bajaMasSche").html("");
 | 
			
		||||
        $("#detMasDiv").data("devnum", subData.device_number);
 | 
			
		||||
        // 電梯管理 Modal 切換到 detail 頁面
 | 
			
		||||
        modalTogDiv("#eleManModal", "#tabDiv", "#detMasDiv", "next", function () {
 | 
			
		||||
            subDeviceSetEleManNotSerFloor(master);
 | 
			
		||||
            let devNumPath = subData.device_number?.split("_").join("/");
 | 
			
		||||
            let ifHtml = `<iframe src="/ord?station:%7Cslot:${devNumPath}/Sch_FLS|view:?fullScreen=true" width="100%" height="100%" style="height:30rem"></iframe>`
 | 
			
		||||
            $("#bajaMasSche").html(ifHtml);
 | 
			
		||||
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    // 電梯管理 Modal 不服務樓層 設定不服務樓層(BAJA)
 | 
			
		||||
    onEvent("change", "#notSerFloTable [name^=notSerChk]", function () {
 | 
			
		||||
        let devNum = $("#detMasDiv").data("devnum");
 | 
			
		||||
        let devNumPath = devNum?.split("_").join("/");
 | 
			
		||||
        let checked = $(this).prop("checked");
 | 
			
		||||
        let tarPoint = $(this).data("point");
 | 
			
		||||
        require(['baja!'], function (baja) {
 | 
			
		||||
            baja.Ord.make(`local:|foxs:|station:|slot:/${devNumPath}`).get()
 | 
			
		||||
                .then(function (folder) {
 | 
			
		||||
                    folder.getSlots().isComponent().eachValue(function (point) {
 | 
			
		||||
                        if (point.getDisplayName() == tarPoint) {
 | 
			
		||||
                            point.set1({
 | 
			
		||||
                                value: checked
 | 
			
		||||
                            })
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    // 電梯管理 Modal 設備 設定點位(BAJA)
 | 
			
		||||
    onEvent("change", "#eleManDevTable input:checkbox", function () {
 | 
			
		||||
        let devNum = $("#detDevDiv").data("devnum");
 | 
			
		||||
        let tarPoint = $(this).data("point");
 | 
			
		||||
        let checked = $(this).prop("checked");
 | 
			
		||||
        let devNumPath = devNum?.split("_").join("/");
 | 
			
		||||
        require(['baja!'], function (baja) {
 | 
			
		||||
            baja.Ord.make(`local:|foxs:|station:|slot:/${devNumPath}`).get()
 | 
			
		||||
                .then(function (folder) {
 | 
			
		||||
                    folder.getSlots().isComponent().eachValue(function (point) {
 | 
			
		||||
                        if (point.getDisplayName() == tarPoint) {
 | 
			
		||||
                            point.set1({
 | 
			
		||||
                                value: checked
 | 
			
		||||
                            })
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    // 切換 modal 內 div 頁面
 | 
			
		||||
    function modalTogDiv(modal, div1, div2, type = "next", callback = null) {
 | 
			
		||||
        $(modal).find(div1).parent("div").css("overflow", "hidden");
 | 
			
		||||
@ -1467,7 +1557,7 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //=====================================================================
 | 
			
		||||
    //                             樓層平面圖
 | 
			
		||||
    //                         ↓  樓層平面圖  ↓
 | 
			
		||||
    //=====================================================================
 | 
			
		||||
    function getDevice(devList) {
 | 
			
		||||
        let selected_floor = devList[0];
 | 
			
		||||
@ -1543,7 +1633,7 @@
 | 
			
		||||
            }
 | 
			
		||||
            return item;
 | 
			
		||||
        });
 | 
			
		||||
        console.log(currentData)
 | 
			
		||||
        
 | 
			
		||||
        if (currentData == null || currentData.length == 0) {
 | 
			
		||||
            this.currentData = [];
 | 
			
		||||
        }
 | 
			
		||||
@ -1570,7 +1660,6 @@
 | 
			
		||||
        resetData();
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function initChart() {
 | 
			
		||||
        let chartDom = $("#floChart")[0];
 | 
			
		||||
        floChart = echarts.init(chartDom, null, { width: 'auto' });
 | 
			
		||||
@ -1590,7 +1679,7 @@
 | 
			
		||||
                // animationDurationUpdate: 1500,
 | 
			
		||||
                tooltip: {
 | 
			
		||||
                    formatter: function (params) {
 | 
			
		||||
                        console.log("23", params)
 | 
			
		||||
                        
 | 
			
		||||
                        if (params.data.device_node_guid != undefined && params.data.device_node_guid != null && params.data.device_node_guid != "") {
 | 
			
		||||
                            return `名稱:${params.data.device_node_full_name}<br>
 | 
			
		||||
                                    Guid:${params.data.device_node_guid}`
 | 
			
		||||
@ -2241,4 +2330,23 @@
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //=====================================================================
 | 
			
		||||
    //                         ↑  樓層平面圖  ↑
 | 
			
		||||
    //=====================================================================
 | 
			
		||||
 | 
			
		||||
    //載入3D模型
 | 
			
		||||
    function load3DModel() {
 | 
			
		||||
        
 | 
			
		||||
        launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6LW1vZGVsX3Rlc3QxMTIxLyVFMyU4MCU5MFRFU1QlRTMlODAlOTEubndk');
 | 
			
		||||
        setElevatorSpeed(0.2)
 | 
			
		||||
        setElevatorFloor(3)
 | 
			
		||||
        movElevator()
 | 
			
		||||
    }
 | 
			
		||||
    function show3D() {
 | 
			
		||||
        if (isFirstLoad3D) {
 | 
			
		||||
            isFirstLoad3D = false;
 | 
			
		||||
            load3DModel();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
</script>
 | 
			
		||||
@ -55,6 +55,12 @@ label[id$='-error'].error {
 | 
			
		||||
    animation: flashing-c 0.5s linear infinite;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.light-flash-c-bd {
 | 
			
		||||
    --flash-color-1: #ffa100;
 | 
			
		||||
    --flash-color-2: #26272b;
 | 
			
		||||
    animation: flashing-c-bd 0.5s linear infinite;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* checkbox switch */
 | 
			
		||||
input.toggle:checked::before {
 | 
			
		||||
   content: '';
 | 
			
		||||
@ -131,6 +137,23 @@ input.toggle:checked {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@keyframes flashing-c-bd {
 | 
			
		||||
    0% {
 | 
			
		||||
        border-color: var(--flash-color-1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    49% {
 | 
			
		||||
        border-color: var(--flash-color-1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    50% {
 | 
			
		||||
        border-color: var(--flash-color-2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    99% {
 | 
			
		||||
        border-color: var(--flash-color-2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/* ================================================================ */
 | 
			
		||||
/*                             單一方法                             */
 | 
			
		||||
/* ================================================================ */
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@
 | 
			
		||||
        <button id="1F1oor" onclick="move1Floor()">1 Floor</button>
 | 
			
		||||
        <button id="2F1oor" onclick="move2Floor()">2 Floor</button>
 | 
			
		||||
        <button id="3F1oor" onclick="move3Floor()">3 Floor</button>
 | 
			
		||||
        <input id="lightBar" type="range" min="0" max="100" step="5" onchange="changeLightPower()">亮度
 | 
			
		||||
        <!-- <input type="range">Main Axis</input> -->
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
@ -55,8 +56,11 @@
 | 
			
		||||
        $(document).ready(function () {
 | 
			
		||||
            //launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6dnNjb2RlX2ZvcmdlX3Rlc3QvJUUzJTgwJTkwJUU2JUIwJUI4JUU2JTk4JUE1JUU2JUEzJUE3JUUzJTgwJTkxJUUzJTgwJTkwTUVQJUUzJTgwJTkxVjMubndk');
 | 
			
		||||
            //launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6dnNjb2RlX2ZvcmdlX3Rlc3QvJUUzJTgwJTkwTUVQJUUzJTgwJTkxLm53Yw');//[TEST].nwd
 | 
			
		||||
            launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6LW1vZGVsX3Rlc3QxMTIxLyVFMyU4MCU5MFRFU1QlRTMlODAlOTEubndk');
 | 
			
		||||
            //launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6LW1vZGVsX3Rlc3QxMTIxLyVFMyU4MCU5MFRFU1QlRTMlODAlOTEubndk');
 | 
			
		||||
 | 
			
		||||
            launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6dGEzaHFzZmZ6cWJub3V4a3BsZGt1a3NldzRzajIxdzUtYmltc19tb2RlbHMvJUUzJTgwJTkwTUVQJUUzJTgwJTkxLm53Yw==');
 | 
			
		||||
            //
 | 
			
		||||
            //launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6dGEzaHFzZmZ6cWJub3V4a3BsZGt1a3NldzRzajIxdzUtYmltc19tb2RlbHMvJUUzJTgwJTkwVEVTVCVFMyU4MCU5MS5ud2Q=');
 | 
			
		||||
            
 | 
			
		||||
        });
 | 
			
		||||
        function move1Floor() {
 | 
			
		||||
@ -74,6 +78,13 @@
 | 
			
		||||
            setElevatorFloor(2);
 | 
			
		||||
            requestAnimationFrame(movElevator);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function changeLightPower() {
 | 
			
		||||
            var value = document.getElementById('lightBar').value;
 | 
			
		||||
            console.log("power: " + value);
 | 
			
		||||
            setLightPower(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    </script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
    <link rel="stylesheet" media="screen, print" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap4.min.css">
 | 
			
		||||
    <link rel="stylesheet" href="css/site.css" />
 | 
			
		||||
    <link rel="stylesheet" href="css/yourteam/plugins/yt-tooltip/yt-tooltip.css" />
 | 
			
		||||
    <link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css" type="text/css">
 | 
			
		||||
</head>
 | 
			
		||||
<!-- BEGIN Body -->
 | 
			
		||||
<!-- Possible Classes
 | 
			
		||||
@ -2527,11 +2528,16 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
    <!--The order of scripts is irrelevant. Please check out the plugin pages for more details about these plugins below:-->
 | 
			
		||||
    <script src="lib/statistics/easypiechart/easypiechart.bundle.js"></script>
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    <!--Bajascript-->
 | 
			
		||||
    <script src="js/bajascript/bscriptReq.js"></script>
 | 
			
		||||
    <!--<script type='text/javascript' src='/module/js/com/tridium/js/ext/require/require.min.js?version=1496767636459'></script>-->
 | 
			
		||||
    <script src='js/bajascript/require.js'></script>
 | 
			
		||||
 | 
			
		||||
    <script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.js"></script>
 | 
			
		||||
    <script src="js/forge/forgemodel.js"></script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <script type='text/javascript'>
 | 
			
		||||
        define('niagaraSystemProperties', function () {
 | 
			
		||||
@ -2543,6 +2549,8 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
    <script src="js/bajascript/require.config.js"></script>
 | 
			
		||||
    <script src="js/FileSaver.js"></script>
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    <script>
 | 
			
		||||
        /*$('#js-page-content').smartPanel();*/
 | 
			
		||||
        var jwt = localStorage.getItem("JWT-Authorization");
 | 
			
		||||
@ -2552,6 +2560,10 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
            location.href = "login.html";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (location.href.indexOf("ord") != -1) {
 | 
			
		||||
            location.href = "/file/index.html"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $(function () {
 | 
			
		||||
            // 二次引用 jquery.js
 | 
			
		||||
            // - 在 require 內部程序需要引用 jquery,由於 require 的套件需要依賴 jquery ,就算 HTML 已經引用 jquery, require 也無法參考
 | 
			
		||||
 | 
			
		||||
@ -1,53 +1,53 @@
 | 
			
		||||
var viewer;
 | 
			
		||||
 | 
			
		||||
const devices = [
 | 
			
		||||
    {
 | 
			
		||||
        id: "Sensor 1",
 | 
			
		||||
        position: {
 | 
			
		||||
            x: -22.779729106182415,
 | 
			
		||||
            y: 5.431043023608719,
 | 
			
		||||
            z: 4.553068469137088,
 | 
			
		||||
        },
 | 
			
		||||
        type: "combo",
 | 
			
		||||
        sensorTypes: ["temperature", "co2"],
 | 
			
		||||
        dbId: 1,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        id: "Sensor 2",
 | 
			
		||||
        position: {
 | 
			
		||||
            x: 0.20752051811882666,
 | 
			
		||||
            y: 5.431043023608719,
 | 
			
		||||
            z: 4.553068469137088,
 | 
			
		||||
        },
 | 
			
		||||
        type: "combo",
 | 
			
		||||
        sensorTypes: ["temperature", "co2"],
 | 
			
		||||
        dbId: 2,
 | 
			
		||||
    },
 | 
			
		||||
];
 | 
			
		||||
// const devices = [
 | 
			
		||||
//     {
 | 
			
		||||
//         id: "Sensor 1",
 | 
			
		||||
//         position: {
 | 
			
		||||
//             x: -22.779729106182415,
 | 
			
		||||
//             y: 5.431043023608719,
 | 
			
		||||
//             z: 4.553068469137088,
 | 
			
		||||
//         },
 | 
			
		||||
//         type: "combo",
 | 
			
		||||
//         sensorTypes: ["temperature", "co2"],
 | 
			
		||||
//         dbId: 1,
 | 
			
		||||
//     },
 | 
			
		||||
//     {
 | 
			
		||||
//         id: "Sensor 2",
 | 
			
		||||
//         position: {
 | 
			
		||||
//             x: 0.20752051811882666,
 | 
			
		||||
//             y: 5.431043023608719,
 | 
			
		||||
//             z: 4.553068469137088,
 | 
			
		||||
//         },
 | 
			
		||||
//         type: "combo",
 | 
			
		||||
//         sensorTypes: ["temperature", "co2"],
 | 
			
		||||
//         dbId: 2,
 | 
			
		||||
//     },
 | 
			
		||||
// ];
 | 
			
		||||
 | 
			
		||||
var sensorStyleDefinitions = {
 | 
			
		||||
    co2: {
 | 
			
		||||
        url: "https://d2zqnmauvnpnnm.cloudfront.net/assets-1/images/co2.svg",
 | 
			
		||||
        color: 0xffffff,
 | 
			
		||||
    },
 | 
			
		||||
    temperature: {
 | 
			
		||||
        url: "https://d2zqnmauvnpnnm.cloudfront.net/assets-1/images/thermometer.svg",
 | 
			
		||||
        color: 0xffffff,
 | 
			
		||||
    },
 | 
			
		||||
    default: {
 | 
			
		||||
        url: "https://d2zqnmauvnpnnm.cloudfront.net/assets-1/images/circle.svg",
 | 
			
		||||
        color: 0xffffff,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
// var sensorStyleDefinitions = {
 | 
			
		||||
//     co2: {
 | 
			
		||||
//         url: "https://d2zqnmauvnpnnm.cloudfront.net/assets-1/images/co2.svg",
 | 
			
		||||
//         color: 0xffffff,
 | 
			
		||||
//     },
 | 
			
		||||
//     temperature: {
 | 
			
		||||
//         url: "https://d2zqnmauvnpnnm.cloudfront.net/assets-1/images/thermometer.svg",
 | 
			
		||||
//         color: 0xffffff,
 | 
			
		||||
//     },
 | 
			
		||||
//     default: {
 | 
			
		||||
//         url: "https://d2zqnmauvnpnnm.cloudfront.net/assets-1/images/circle.svg",
 | 
			
		||||
//         color: 0xffffff,
 | 
			
		||||
//     },
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
// Initialize sensor values
 | 
			
		||||
let sensorVals = [];
 | 
			
		||||
//let sensorVals = [];
 | 
			
		||||
let fragProxy;
 | 
			
		||||
var targetFloorZ;
 | 
			
		||||
var elevatorSpeed;
 | 
			
		||||
for (let i = 0; i < devices.length; i++) {
 | 
			
		||||
    sensorVals[i] = Math.random();
 | 
			
		||||
}
 | 
			
		||||
// for (let i = 0; i < devices.length; i++) {
 | 
			
		||||
//     sensorVals[i] = Math.random();
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
function launchViewer(urn) {
 | 
			
		||||
    var options = {
 | 
			
		||||
@ -57,6 +57,7 @@ function launchViewer(urn) {
 | 
			
		||||
 | 
			
		||||
    Autodesk.Viewing.Initializer(options, () => {
 | 
			
		||||
        viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('forgeViewer'));
 | 
			
		||||
        //viewer = new Autodesk.Viewing.Viewer3D(document.getElementById('forgeViewer'));
 | 
			
		||||
        viewer.start();
 | 
			
		||||
        var documentId = 'urn:' + urn;
 | 
			
		||||
        Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
 | 
			
		||||
@ -64,26 +65,26 @@ function launchViewer(urn) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //test 
 | 
			
		||||
        for (let i = 0; i < urn.length; i++) {
 | 
			
		||||
            Autodesk.Viewing.Document.load(urn[i]["urn"], async (doc) => {
 | 
			
		||||
                let viewables = doc.getRoot().getDefaultGeometry();
 | 
			
		||||
                let model = await viewer.loadDocumentNode(doc, viewables, {
 | 
			
		||||
                    preserveView: false,
 | 
			
		||||
                    keepCurrentModels: true,
 | 
			
		||||
                    placementTransform: (new THREE.Matrix4()).setPosition(urn[i]["xform"]),
 | 
			
		||||
                    keepCurrentModels: true,
 | 
			
		||||
                    globalOffset: {
 | 
			
		||||
                        x: 0,
 | 
			
		||||
                        y: 0,
 | 
			
		||||
                        z: 0
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
        // for (let i = 0; i < urn.length; i++) {
 | 
			
		||||
        //     Autodesk.Viewing.Document.load(urn[i]["urn"], async (doc) => {
 | 
			
		||||
        //         let viewables = doc.getRoot().getDefaultGeometry();
 | 
			
		||||
        //         let model = await viewer.loadDocumentNode(doc, viewables, {
 | 
			
		||||
        //             preserveView: false,
 | 
			
		||||
        //             keepCurrentModels: true,
 | 
			
		||||
        //             placementTransform: (new THREE.Matrix4()).setPosition(urn[i]["xform"]),
 | 
			
		||||
        //             keepCurrentModels: true,
 | 
			
		||||
        //             globalOffset: {
 | 
			
		||||
        //                 x: 0,
 | 
			
		||||
        //                 y: 0,
 | 
			
		||||
        //                 z: 0
 | 
			
		||||
        //             }
 | 
			
		||||
        //         });
 | 
			
		||||
 | 
			
		||||
                await viewer.waitForLoadDone(); //!<<< Wait for loading materials, properties and geometries for this model (URN)
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        //         await viewer.waitForLoadDone(); //!<<< Wait for loading materials, properties and geometries for this model (URN)
 | 
			
		||||
        //     });
 | 
			
		||||
        // }
 | 
			
		||||
 | 
			
		||||
        loadHeatmaps(viewer.getAllModels()[0]); //!<<< equals to viewer.model
 | 
			
		||||
        //loadHeatmaps(viewer.getAllModels()[0]); //!<<< equals to viewer.model
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -122,55 +123,34 @@ function onDocumentLoadSuccess(doc) {
 | 
			
		||||
    viewer.loadDocumentNode(doc, viewables).then(i => {
 | 
			
		||||
        // documented loaded, any action?
 | 
			
		||||
    });
 | 
			
		||||
    viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => {
 | 
			
		||||
        var currSelection = viewer.getSelection();
 | 
			
		||||
        var domElem = document.getElementById('id_printer');
 | 
			
		||||
        domElem.innerText = currSelection[0];
 | 
			
		||||
    });
 | 
			
		||||
    // viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => {
 | 
			
		||||
    //     var currSelection = viewer.getSelection();
 | 
			
		||||
    //     var domElem = document.getElementById('id_printer');
 | 
			
		||||
    //     domElem.innerText = currSelection[0];
 | 
			
		||||
    // });
 | 
			
		||||
 | 
			
		||||
    viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, function () {
 | 
			
		||||
        var instanceTree = viewer.model.getData().instanceTree;
 | 
			
		||||
        var allDbIdsStr = Object.keys(instanceTree.nodeAccess.dbIdToIndex);
 | 
			
		||||
        var domElem = document.getElementById('all_id');
 | 
			
		||||
        domElem.innerText = allDbIdsStr;
 | 
			
		||||
        //allDbIdsStr.map(function (id) { return parseInt(id) });
 | 
			
		||||
        //getAllLeafComponents(viewer, function (jsonData) {
 | 
			
		||||
        //    console.log("data: " + jsonData);
 | 
			
		||||
        //});
 | 
			
		||||
        //var a = getAllDbIds(viewer);
 | 
			
		||||
        //console.log("a: " + a);//10952
 | 
			
		||||
    //viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, function () {
 | 
			
		||||
        // var instanceTree = viewer.model.getData().instanceTree;
 | 
			
		||||
        // var allDbIdsStr = Object.keys(instanceTree.nodeAccess.dbIdToIndex);
 | 
			
		||||
        // var domElem = document.getElementById('all_id');
 | 
			
		||||
        // domElem.innerText = allDbIdsStr;
 | 
			
		||||
 | 
			
		||||
        let tree = viewer.model.getData().instanceTree;
 | 
			
		||||
        let nodeId = 10952;
 | 
			
		||||
        // let tree = viewer.model.getData().instanceTree;
 | 
			
		||||
        // let nodeId = 10952;
 | 
			
		||||
 | 
			
		||||
        tree.enumNodeFragments(nodeId, function (frag) {
 | 
			
		||||
            fragProxy = viewer.impl.getFragmentProxy(viewer.model, frag);
 | 
			
		||||
            fragProxy.getAnimTransform();
 | 
			
		||||
            //fragProxy.quaternion = new THREE.Quaternion().setFromAxisAngle(
 | 
			
		||||
            //    new THREE.Vector3(0, 0.3, 0),
 | 
			
		||||
            //    -Math.PI / 2);
 | 
			
		||||
            //fragProxy.quaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0));
 | 
			
		||||
            //fragProxy.quaternion = new THREE.Quaternion().setPosition(new THREE.Vector3(10, 5, 0), 5);
 | 
			
		||||
            //fragProxy.updateAnimTransform();
 | 
			
		||||
            //do some work with fragment proxy
 | 
			
		||||
        // tree.enumNodeFragments(nodeId, function (frag) {
 | 
			
		||||
        //     fragProxy = viewer.impl.getFragmentProxy(viewer.model, frag);
 | 
			
		||||
        //     fragProxy.getAnimTransform();
 | 
			
		||||
        //     let fragPosition = new THREE.Vector3(0, 0, 0);// 一樓0 二樓15 三樓 26
 | 
			
		||||
 | 
			
		||||
        //     fragProxy.position = fragPosition
 | 
			
		||||
 | 
			
		||||
            //var fragPosition = new THREE.Vector3(
 | 
			
		||||
            //    10 - fragProxy.offset.x,
 | 
			
		||||
            //    10 - fragProxy.offset.y,
 | 
			
		||||
            //    10 - fragProxy.offset.z)
 | 
			
		||||
        //     fragProxy.updateAnimTransform()
 | 
			
		||||
 | 
			
		||||
        // });
 | 
			
		||||
        // viewer.impl.sceneUpdated(true);
 | 
			
		||||
 | 
			
		||||
            let fragPosition = new THREE.Vector3(0, 0, 0);// 一樓0 二樓15 三樓 26
 | 
			
		||||
 | 
			
		||||
            fragProxy.position = fragPosition
 | 
			
		||||
 | 
			
		||||
            fragProxy.updateAnimTransform()
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
        viewer.impl.sceneUpdated(true);
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
    //});
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,39 @@ function addzero(num) {
 | 
			
		||||
 * @param {any} alarmClass
 | 
			
		||||
 * @param {any} callback
 | 
			
		||||
 */
 | 
			
		||||
// function getAlarmByBaja(startDate_millisecond, endDate_millisecond, isRecover, isAck, alarmClass, callback) {
 | 
			
		||||
//     let _sourceTmp;
 | 
			
		||||
//     var _result = "";
 | 
			
		||||
//     var _ss = "";
 | 
			
		||||
//     var _bfName = "";
 | 
			
		||||
//     var _sourceName = "";
 | 
			
		||||
//     var _index = 0;
 | 
			
		||||
//     var _recoverState = isRecover ? "!= null" : "= null";
 | 
			
		||||
//     var _ackState = isAck ? "= 1" : "!= 1";
 | 
			
		||||
 | 
			
		||||
//     require(['baja!'], function (baja) {
 | 
			
		||||
//         baja.Ord.make("local:|foxs:|alarm:|bql:select timestamp, ackState, alarmClass, alarmClassDisplayName, alarmValue, alarmData, alarmData.sourceName, uuid, alarmData.msgText, alarmData.numericValue, alarmData.presentValue, alarmData.status, alarmData.toState, normalTime from openAlarms where alarmClass = '" + alarmClass + "' and timestamp.millis > " + startDate_millisecond + " and timestamp.millis < " + endDate_millisecond + " and normalTime " + _recoverState + " order by timestamp asc").get()
 | 
			
		||||
//             .then(function (table) {
 | 
			
		||||
//                 return table.cursor({
 | 
			
		||||
//                     each: function (record) {
 | 
			
		||||
//                         _sourceTmp = (record.get('alarmData').get('sourceName')).toString().split('_');
 | 
			
		||||
//                         _bfName = _sourceTmp[1] + "-" + _sourceTmp[4];
 | 
			
		||||
//                         _sourceName = _sourceTmp[7] + "-" + _sourceTmp[8];
 | 
			
		||||
//                         _ss += ', "' + _index + '": {"buildingFloorName_zh":"' + _bfName + '", "uuid":"' + record.get('uuid') + '", "timestamp":"' + record.get('timestamp') + '", "alarmClass":"' + record.get('alarmClass') + '", "sourceName_zh":"' + _sourceName + '", "msgText":"' + record.get('alarmData').get('msgText') + '", "ackState":"' + record.get('ackState') + '", "normalTime":"' + record.get('normalTime') + '"}';
 | 
			
		||||
//                         _index++;
 | 
			
		||||
//                     },
 | 
			
		||||
//                     after: function () {
 | 
			
		||||
//                         _result += '{' + '"count": ' + _index;
 | 
			
		||||
//                         _result += _ss;
 | 
			
		||||
//                         _result += '}';
 | 
			
		||||
//                         if (typeof callback === 'function') {
 | 
			
		||||
//                             callback(_result);
 | 
			
		||||
//                         }
 | 
			
		||||
//                     }
 | 
			
		||||
//                 });
 | 
			
		||||
//             });
 | 
			
		||||
//     });
 | 
			
		||||
// }
 | 
			
		||||
function getAlarmByBaja(startDate_millisecond, endDate_millisecond, isRecover, isAck, alarmClass, callback) {
 | 
			
		||||
    let _sourceTmp;
 | 
			
		||||
    var _result = "";
 | 
			
		||||
@ -57,6 +90,35 @@ function getAlarmByBaja(startDate_millisecond, endDate_millisecond, isRecover, i
 | 
			
		||||
 * @param {any} devicePath
 | 
			
		||||
 * @param {any} callback
 | 
			
		||||
 */
 | 
			
		||||
// function getOneDeviceAlarmTop10ByBaja(devicePath, callback) {
 | 
			
		||||
//     var _result = "";
 | 
			
		||||
//     var _ss = "";
 | 
			
		||||
//     var _index = 0;
 | 
			
		||||
//     //{ "count":2,"data": [{ "time": "2022/11/14 15:00:00", "errId": "0001", "ackCheck": "未確認", "errReason": "燈泡故障" }, { "time": "2022/11/14 15:00:00", "errId": "0002", "ackCheck": "未確認", "errReason": "燈泡故障" }]}
 | 
			
		||||
//     require(['baja!'], function (baja) {
 | 
			
		||||
//         baja.Ord.make("local:|foxs:|alarm:|bql:select top 10 timestamp, ackState, alarmData, alarmData.sourceName, sourceState, uuid, alarmData.msgText, normalTime where alarmData.sourceName like '%" + devicePath + "%' order by timestamp desc").get()
 | 
			
		||||
//             .then(function (table) {
 | 
			
		||||
//                 return table.cursor({
 | 
			
		||||
//                     each: function (record) {
 | 
			
		||||
//                         if (_index == 0)
 | 
			
		||||
//                             _ss += '{"uuid":"' + record.get('uuid') + '", "msgText":"' + record.get('alarmData').get('msgText') + '", "ackState":"' + record.get('ackState') + '", "timestamp":"' + record.get('timestamp') + '"}';
 | 
			
		||||
//                         else
 | 
			
		||||
//                             _ss += ',{"uuid":"' + record.get('uuid') + '", "msgText":"' + record.get('alarmData').get('msgText') + '", "ackState":"' + record.get('ackState') + '", "timestamp":"' + record.get('timestamp') + '"}';
 | 
			
		||||
//                         _index++;
 | 
			
		||||
//                     },
 | 
			
		||||
//                     after: function () {
 | 
			
		||||
//                         _result += '{' + '"count": ' + _index +', "data":[';
 | 
			
		||||
 | 
			
		||||
//                         _result += _ss+']';
 | 
			
		||||
//                         _result += '}';
 | 
			
		||||
//                         if (typeof callback === 'function') {
 | 
			
		||||
//                             callback(_result);
 | 
			
		||||
//                         }
 | 
			
		||||
//                     }
 | 
			
		||||
//                 });
 | 
			
		||||
//             });
 | 
			
		||||
//     });
 | 
			
		||||
// }
 | 
			
		||||
function getOneDeviceAlarmTop10ByBaja(devicePath, callback) {
 | 
			
		||||
    var _result = "";
 | 
			
		||||
    var _ss = "";
 | 
			
		||||
@ -109,6 +171,31 @@ function getOneDeviceAlarmTop10ByBaja(devicePath, callback) {
 | 
			
		||||
 * @param {any} systemPath
 | 
			
		||||
 * @param {any} callback
 | 
			
		||||
 */
 | 
			
		||||
// function getOneSystemAlarmStateByBaja(systemPath, callback) {
 | 
			
		||||
//     var _result = "";
 | 
			
		||||
//     var _ss = "";
 | 
			
		||||
//     var _index = 0;
 | 
			
		||||
 | 
			
		||||
//     require(['baja!'], function (baja) {
 | 
			
		||||
//         baja.Ord.make("local:|foxs:|alarm:|bql:select alarmData, alarmData.sourceName, sourceState, uuid where alarmData.sourceName like '%" + systemPath + "%' order by timestamp desc").get()
 | 
			
		||||
//             .then(function (table) {
 | 
			
		||||
//                 return table.cursor({
 | 
			
		||||
//                     each: function (record) {
 | 
			
		||||
//                         _ss += ', "' + _index + '": {"uuid":"' + record.get('uuid') + '", "sourceName":"' + record.get('alarmData').get('sourceName') + '", "sourceState":"' + record.get('sourceState') + '"}';
 | 
			
		||||
//                         _index++;
 | 
			
		||||
//                     },
 | 
			
		||||
//                     after: function () {
 | 
			
		||||
//                         _result += '{' + '"count": ' + _index;
 | 
			
		||||
//                         _result += _ss;
 | 
			
		||||
//                         _result += '}';
 | 
			
		||||
//                         if (typeof callback === 'function') {
 | 
			
		||||
//                             callback(_result);
 | 
			
		||||
//                         }
 | 
			
		||||
//                     }
 | 
			
		||||
//                 });
 | 
			
		||||
//             });
 | 
			
		||||
//     });
 | 
			
		||||
// }
 | 
			
		||||
function getOneSystemAlarmStateByBaja(systemPath, callback) {
 | 
			
		||||
    var _result = "";
 | 
			
		||||
    var _ss = "";
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,9 @@
 | 
			
		||||
let baja_subscribe_device_callback_func; //設定BQL訂閱之後要回傳的Function
 | 
			
		||||
let baja_my_user_account_func;    //取得帳號資料要回傳的Function
 | 
			
		||||
var ordPath; //當前點選選單的tag,用來抓出設備路徑,例如:旅館棟->H,消防偵煙器->F3
 | 
			
		||||
window.tolSubList = [];
 | 
			
		||||
 | 
			
		||||
var user_name = "";
 | 
			
		||||
function subscriptionDevices() {
 | 
			
		||||
    // 用BQL的方式去訂閱
 | 
			
		||||
    this.setSubscribeDevicesByBql = function (tempOrdPath) {
 | 
			
		||||
@ -13,6 +16,16 @@ function subscriptionDevices() {
 | 
			
		||||
            baja_subscribe_device_callback_func = callBackFunc;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function MyBaja() {
 | 
			
		||||
    // 取得使用者帳號
 | 
			
		||||
    this.setMyUserAccount = function (callBackFunc) {
 | 
			
		||||
        if (callBackFunc != undefined && callBackFunc != null) {
 | 
			
		||||
            baja_my_user_account_func = callBackFunc;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -270,7 +283,12 @@ function getElevatorInfoByBaja(path, callback) {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
require(['baja!'], function (baja) {
 | 
			
		||||
    user_name = baja.getUserName();
 | 
			
		||||
    if (baja_my_user_account_func != undefined && baja_my_user_account_func != null) {
 | 
			
		||||
        baja_my_user_account_func(user_name);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// baja.Ord.make('ip:greencloud.fic.com.tw|foxs:|station:|slot:/Arena/H/F3|bql:select name, displayname, slotPath, out.value, out from control:ControlPoint')
 | 
			
		||||
// // baja.Ord.make('ip:greencloud.fic.com.tw|foxs:|station:|slot:/Arena/H/E1/B1F/TestData/H_E1_B1F_TestData_Data|bql:select slotPath,out.value from control:NumericWritable')
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								Frontend/js/n4js/electricmeterbaja.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Frontend/js/n4js/electricmeterbaja.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 取得電表總計資料 by baja
 | 
			
		||||
 * @param {any} devicePath 
 | 
			
		||||
 * @param {any} timeType
 | 
			
		||||
 * @param {any} callback
 | 
			
		||||
 */
 | 
			
		||||
function getElectricMeterTotalByBaja(devicePath, timeType, callback) {
 | 
			
		||||
    var _result = "";
 | 
			
		||||
    var _ss = "";
 | 
			
		||||
    var _index = 0;
 | 
			
		||||
 | 
			
		||||
    require(['baja!'], function (baja) {
 | 
			
		||||
        console.log('transform:slot:/' + devicePath + '/History/' + timeType);
 | 
			
		||||
        baja.Ord.make('transform:slot:/' + devicePath + '/History/' + timeType).get()
 | 
			
		||||
            .then(function (table) {
 | 
			
		||||
                return table.cursor({
 | 
			
		||||
                    each: function (record) {
 | 
			
		||||
                        if (_index == 0)
 | 
			
		||||
                            _ss += '{"timestamp":"' + record.get('timestamp') + '", "MP1":' + record.get('MP1') + '"}';
 | 
			
		||||
                        else
 | 
			
		||||
                            _ss += ',{"timestamp":"' + record.get('timestamp') + '", "MP1":' + record.get('MP1') + '"}';
 | 
			
		||||
                        _index++;
 | 
			
		||||
                    },
 | 
			
		||||
                    after: function () {
 | 
			
		||||
                        _result += '{' + '"count": ' + _index + ', "data":[';
 | 
			
		||||
                        _result += _ss;
 | 
			
		||||
                        _result += ']}';
 | 
			
		||||
                        if (typeof callback === 'function') {
 | 
			
		||||
                            callback(_result);
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    limit: -1,
 | 
			
		||||
                    offset: 0
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
@ -8,6 +8,32 @@
 | 
			
		||||
 * @param {any} company
 | 
			
		||||
 * @param {any} callback
 | 
			
		||||
 */
 | 
			
		||||
// function getHistoryDataByBaja(devicePath, startDate_millisecond, endDate_millisecond, deviceName, company, callback) {
 | 
			
		||||
//     var _result = "";
 | 
			
		||||
//     var _ss = "";
 | 
			
		||||
//     var _index = 0;
 | 
			
		||||
 | 
			
		||||
//     require(['baja!'], function (baja) {
 | 
			
		||||
//         baja.Ord.make('local:|foxs:|history:/' + company + '/' + devicePath + '|bql:select * from control:ControlPoint where timestamp.millis > ' + startDate_millisecond + ' and timestamp.millis < ' + endDate_millisecond).get()
 | 
			
		||||
//             .then(function (table) {
 | 
			
		||||
//                 return table.cursor({
 | 
			
		||||
//                     each: function (record) {
 | 
			
		||||
//                         _ss += ', "' + _index + '": {"deviceName":"' + deviceName + '", "value":' + record.get('value') + ', "timestamp":"' + record.get('timestamp') + '"}';
 | 
			
		||||
//                         _index++;
 | 
			
		||||
//                     },
 | 
			
		||||
//                     after: function () {
 | 
			
		||||
//                         _result += '{' + '"count": ' + _index;
 | 
			
		||||
//                         _result += _ss;
 | 
			
		||||
//                         _result += '}';
 | 
			
		||||
//                         if (typeof callback === 'function') {
 | 
			
		||||
//                             callback(_result);
 | 
			
		||||
//                         }
 | 
			
		||||
//                     }
 | 
			
		||||
//                 });
 | 
			
		||||
//             });
 | 
			
		||||
//     });
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
function getHistoryDataByBaja(devicePath, startDate_millisecond, endDate_millisecond, deviceName, company, callback) {
 | 
			
		||||
    var _result = "";
 | 
			
		||||
    var _ss = "";
 | 
			
		||||
 | 
			
		||||
@ -113,18 +113,25 @@ class ElevatorHandler {
 | 
			
		||||
        this.ele = ele;
 | 
			
		||||
        this.eleId = "";
 | 
			
		||||
        this.eleWra = $("<div></div>");
 | 
			
		||||
        this.speed = 0;
 | 
			
		||||
        this.monStatus = 0;  // 0=no 1=up 2=down
 | 
			
		||||
        this.speed = 0.3;
 | 
			
		||||
        this.movStatus = {};  // {id:elevator01,value:0} 0=no 1=up 2=down
 | 
			
		||||
        this.floorHeight = typeof option.fHeight == "undefined" ? 50 : option.fHeight;
 | 
			
		||||
        this.floorWidth = typeof option.fWidth == "undefined" ? 45 : option.fWidth;
 | 
			
		||||
        this.floors = typeof option.floors == "undefined" ? [{}] : option.floors;
 | 
			
		||||
        this.eleCnt = typeof option.eleCnt == "undefined" ? 3 : option.eleCnt;
 | 
			
		||||
        this.elevators = typeof option.elevators == "undefined" ? [{}] : option.elevators;  // {id:elevator01}
 | 
			
		||||
        this.curElevFloor = typeof option.curElevFloor == "undefined" ? {} : option.curElevFloor;
 | 
			
		||||
        this.setTimeout = null;
 | 
			
		||||
        this.init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init = function () {
 | 
			
		||||
        this.setTabWra();
 | 
			
		||||
        this.setTabFloor();
 | 
			
		||||
        if (Object.keys(this.curElevFloor).length != 0) { 
 | 
			
		||||
            $.each(Object.keys(this.curElevFloor), (idx, elevKey) => {
 | 
			
		||||
                this.setElevFloor(elevKey,this.curElevFloor[elevKey]);
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 設置 wrapper
 | 
			
		||||
@ -143,19 +150,27 @@ class ElevatorHandler {
 | 
			
		||||
    setTabFloor = function () {
 | 
			
		||||
        let _w = this.floorWidth, _h = this.floorHeight;
 | 
			
		||||
        let thead = creEle("thead"), tbody = creEle("tbody");
 | 
			
		||||
        let _floors = this.floors, _ele = this.ele, _eleCnt = this.eleCnt;
 | 
			
		||||
        let _floors = this.floors, _ele = this.ele, _elevators = this.elevators;
 | 
			
		||||
        //樓層從小到大
 | 
			
		||||
        _floors = _floors.oSort("sort").reverse().map(x => x.name);
 | 
			
		||||
 | 
			
		||||
        let theadTr = creEle("tr");
 | 
			
		||||
        for (let e = 1; e <= _eleCnt + 2; e++) {
 | 
			
		||||
     
 | 
			
		||||
        for (let e = 1; e <= _elevators.length + 2; e++) {
 | 
			
		||||
            let th = creEle("th");
 | 
			
		||||
            th.css({ "width": `${_w}px`, "height": `${_h}px` });
 | 
			
		||||
            if (e != 1 && e != _eleCnt + 2) {
 | 
			
		||||
            if (e != 1 && e != _elevators.length + 2) {
 | 
			
		||||
                let elevId = _elevators[e - 2]?.id;
 | 
			
		||||
                // 電梯方框
 | 
			
		||||
                let span = creEle("span", null, "elevator-item-" + (e - 1), null, ["elevator-item"]);
 | 
			
		||||
                span.css({ "width": `${_w - 3}px`, "height": `${_h - 3}px`, "top": `1.5px`})
 | 
			
		||||
                let span = creEle("span", null, "elevator-item-" + (elevId), null, ["elevator-item"]);
 | 
			
		||||
                let spanUp = creEle("span", null, null, null, ["elevator-item-toup"]);
 | 
			
		||||
                let spanDown = creEle("span", null, null, null, ["elevator-item-todown"]);
 | 
			
		||||
                span.css({ "width": `${_w - 3}px`, "height": `${_h - 3}px`, "top": `1.5px`, "transition":`transform ${1 / this.speed}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`})
 | 
			
		||||
                spanUp.css({ "width": `${_w - 3}px`, "height": `${(_h - 3) / 2}px`, "top": `1.5px`, "transition":`transform ${1 / this.speed}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`})
 | 
			
		||||
                spanDown.css({ "width": `${_w - 3}px`, "height": `${(_h - 3) / 2}px`, "top": `1.5px`, "transition":`transform ${1 / this.speed}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`,"top":`${1.5 + (_h-3) / 2}px`})
 | 
			
		||||
                th.append(spanUp);
 | 
			
		||||
                th.append(span);
 | 
			
		||||
                th.append(spanDown);
 | 
			
		||||
            }
 | 
			
		||||
            theadTr.append(th);
 | 
			
		||||
        }
 | 
			
		||||
@ -165,13 +180,14 @@ class ElevatorHandler {
 | 
			
		||||
        //樓層表格建置 tbody
 | 
			
		||||
        for (let f = 1; f <= _floors.length; f++) {
 | 
			
		||||
            let tr = creEle("tr");
 | 
			
		||||
            for (let e = 1; e <= _eleCnt + 2; e++) {
 | 
			
		||||
            
 | 
			
		||||
            for (let e = 1; e <= _elevators.length + 2; e++) {
 | 
			
		||||
                let td = creEle("td");
 | 
			
		||||
                td.css({ "width": `${_w}px`, "height": `${_h}px` });
 | 
			
		||||
                if (e == 1) {
 | 
			
		||||
                    td.addClass("t-black")
 | 
			
		||||
                    td.text(_floors[f - 1]);
 | 
			
		||||
                } else if (e == _eleCnt + 2) {
 | 
			
		||||
                } else if (e == _elevators.length + 2) {
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    let div = creDiv(["d-flex", "justify-content-center", "align-items-end", "h-100"]);
 | 
			
		||||
@ -205,5 +221,64 @@ class ElevatorHandler {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setElevFloor = function (elevId, floId) {
 | 
			
		||||
        let curFloId = this.curElevFloor[elevId];
 | 
			
		||||
        let curSort = this.floors.filter(x => x.id == curFloId).map(x => x.sort)[0];
 | 
			
		||||
        let tarSort = this.floors.filter(x => x.id == floId).map(x => x.sort)[0];
 | 
			
		||||
        let gapFloor = tarSort - curSort;
 | 
			
		||||
        let cssEle = [$(`#elevator-item-${elevId}`)[0], $(`#elevator-item-${elevId}`).prev("span.elevator-item-toup")[0], $(`#elevator-item-${elevId}`).next("span.elevator-item-todown")[0]]
 | 
			
		||||
        clearTimeout(this.setTimeout); 
 | 
			
		||||
        console.log("123",this.movStatus)
 | 
			
		||||
        if (this.movStatus[elevId] != 0) { 
 | 
			
		||||
            $(cssEle).css("transition", `transform ${1 / this.speed * Math.abs(gapFloor)}s cubic-bezier(0, 0, 0.62, 1) 0s`);
 | 
			
		||||
        }
 | 
			
		||||
        //if (gapFloor < 0) {
 | 
			
		||||
        //    this.movStatus[elevId] = 2;
 | 
			
		||||
        //} else if (gapFloor > 0) {
 | 
			
		||||
        //    this.movStatus[elevId] = 1;
 | 
			
		||||
        //} else {
 | 
			
		||||
        //    this.movStatus[elevId] = 0;
 | 
			
		||||
        //}
 | 
			
		||||
        this.setTimeout = setTimeout(() => {
 | 
			
		||||
            /*this.movStatus[elevId] = 0;*/
 | 
			
		||||
            $(cssEle).css("transition", `transform ${1 / this.speed * Math.abs(gapFloor)}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`);
 | 
			
		||||
            this.setEleUpDownStyle(elevId);
 | 
			
		||||
        }, (1 / this.speed * Math.abs(gapFloor)) * 1000)
 | 
			
		||||
        this.setEleUpDownStyle(elevId);
 | 
			
		||||
        this.curElevFloor[elevId] = floId;
 | 
			
		||||
        $(cssEle).css("transition", `transform ${1 / this.speed * Math.abs(gapFloor)}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`)
 | 
			
		||||
        $(cssEle).css("transform", `translateY(${this.floorHeight * (this.floors.length - tarSort)}px)`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setEleMovStatus = function (elevId,status) {
 | 
			
		||||
        this.movStatus[elevId] = status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setEleUpDownStyle = function (elevId) {
 | 
			
		||||
        if (this.movStatus[elevId] == 1) {
 | 
			
		||||
            $(`#elevator-item-${elevId}`).prev("span.elevator-item-toup").addClass("light-flash-c-bd")
 | 
			
		||||
                .css("--flash-color-1", "#44ea8e").css("--flash-color-2", "rgba(255,255,255,0)");
 | 
			
		||||
        } else if (this.movStatus[elevId] == 2) {
 | 
			
		||||
            $(`#elevator-item-${elevId}`).next("span.elevator-item-todown").addClass("light-flash-c-bd")
 | 
			
		||||
                .css("--flash-color-1", "#44ea8e").css("--flash-color-2", "rgba(255,255,255,0)");
 | 
			
		||||
        } else {
 | 
			
		||||
            $(`#elevator-item-${elevId}`).prev("span.elevator-item-toup").removeClass("light-flash-c-bd");
 | 
			
		||||
            $(`#elevator-item-${elevId}`).next("span.elevator-item-todown").removeClass("light-flash-c-bd");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setCurElevFloor = function (elevId,floId) {
 | 
			
		||||
        this.curElevFloor[elevId] = floId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    redraw = function () {
 | 
			
		||||
        $(this.ele).empty();
 | 
			
		||||
        this.setTabFloor();
 | 
			
		||||
        if (Object.keys(this.curElevFloor).length != 0) {
 | 
			
		||||
            $.each(Object.keys(this.curElevFloor), (idx, elevKey) => {
 | 
			
		||||
                this.setElevFloor(elevKey, this.curElevFloor[elevKey]);
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@ -19,12 +19,13 @@ $(function () {
 | 
			
		||||
 * 初始全頁面 yt tab
 | 
			
		||||
 * */
 | 
			
		||||
function initTabsByEle() {
 | 
			
		||||
    _ytTabInited = [];
 | 
			
		||||
    $("[data-tabname][data-target]:not([data-tabrole=child])").each(function (index, value) {
 | 
			
		||||
        let tabName = $(value).data("tabname");
 | 
			
		||||
        if (_ytTabInited.indexOf(tabName) == -1) {
 | 
			
		||||
            var ytTab = new YT.Tab({ tabName: tabName })
 | 
			
		||||
            _ytTabInited.push(tabName);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        var ytTab = new YT.Tab({ tabName: tabName })
 | 
			
		||||
        _ytTabInited.push(tabName);
 | 
			
		||||
        
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,7 @@ function fnInitJqDataTablesNoData(tag, dataSet = null, columns = null, columnDef
 | 
			
		||||
        "columns": columns,
 | 
			
		||||
        "aoColumnDefs": columnDefs,
 | 
			
		||||
        "stateSave": true,
 | 
			
		||||
        "pagingType": "simple",
 | 
			
		||||
        "pagingType": "full_numbers",
 | 
			
		||||
        "destroy": false,
 | 
			
		||||
        "initComplete": initComplete,
 | 
			
		||||
        "drawCallback": fnDrawCallBack,
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@
 | 
			
		||||
                        <label class="custom-control-label" for="rememberme"> 記住我</label>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <button type="submit" class="btn btn-default float-right" onclick="Login(event)">登入</button>
 | 
			
		||||
                <button type="submit" class="btn btn-default float-right" onclick="Login(null,event)">登入</button>
 | 
			
		||||
            </form>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="blankpage-footer text-center">
 | 
			
		||||
@ -69,131 +69,190 @@
 | 
			
		||||
        <source src="media/video/cc.mp4" type="video/mp4">
 | 
			
		||||
    </video>
 | 
			
		||||
    <!--Base JS-->
 | 
			
		||||
    <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
 | 
			
		||||
    <!--<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>-->
 | 
			
		||||
    <script src="lib/vendors.bundle.js"></script>
 | 
			
		||||
    <script src="lib/app.bundle.js"></script>
 | 
			
		||||
    <!-- JQuery Validate -->
 | 
			
		||||
    <script src="lib/jquery-validation/dist/jquery.validate.js"></script>
 | 
			
		||||
    <!--<script src="lib/jquery-validation/dist/jquery.validate.js"></script>
 | 
			
		||||
    <script src="lib/jquery-validation/dist/additional-methods.min.js"></script>
 | 
			
		||||
    <script src="lib/jquery-validation/dist/localization/messages_zh_TW.js"></script>
 | 
			
		||||
    <script src="lib/notifications/sweetalert2/sweetalert2.bundle.js"></script>
 | 
			
		||||
    <script src="lib/notifications/sweetalert2/sweetalert2.bundle.js"></script>-->
 | 
			
		||||
    <script src="lib/notifications/toastr/toastr.min.js"></script>
 | 
			
		||||
    <script src="js/toast.js"></script>
 | 
			
		||||
    <script src="js/init.js"></script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <!--Bajascript-->
 | 
			
		||||
    <script src="js/bajascript/bscriptReq.js"></script>
 | 
			
		||||
    <!--<script type='text/javascript' src='/module/js/com/tridium/js/ext/require/require.min.js?version=1496767636459'></script>-->
 | 
			
		||||
    <script src='js/bajascript/require.js'></script>
 | 
			
		||||
 | 
			
		||||
    <script src="js/n4js/bajatest.js"></script>
 | 
			
		||||
    <script src="js/bajascript/require.config.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    var remember = false;
 | 
			
		||||
    var myBaja = null;
 | 
			
		||||
    $(function () {
 | 
			
		||||
        if (localStorage.getItem('taipei-t') == 'true') {
 | 
			
		||||
        require(["jquery"], loadedBasePack);
 | 
			
		||||
    });
 | 
			
		||||
    /**
 | 
			
		||||
    * jquery.js 二次引用後 Callback,載入第三方套件
 | 
			
		||||
    * */
 | 
			
		||||
    function loadedBasePack() {
 | 
			
		||||
        require(
 | 
			
		||||
            [
 | 
			
		||||
                "lib/app.bundle",
 | 
			
		||||
                "lib/app.menu",
 | 
			
		||||
                "lib/jquery-validation/dist/jquery.validate",
 | 
			
		||||
                "lib/jquery-validation/dist/additional-methods.min",
 | 
			
		||||
                "lib/jquery-validation/dist/localization/messages_zh_TW",
 | 
			
		||||
                /*"lib/notifications/sweetalert2/sweetalert2.bundle",*/
 | 
			
		||||
            ], loadedMasterPack);
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
    * 第三方套件引用後 Callback,載入額外套件
 | 
			
		||||
    * */
 | 
			
		||||
    function loadedMasterPack() {
 | 
			
		||||
        require(
 | 
			
		||||
            [
 | 
			
		||||
                "init",
 | 
			
		||||
 | 
			
		||||
            ], loadedJsPack);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function loadedJsPack() {
 | 
			
		||||
        if (location.href.indexOf("localhost:5966") == -1) {
 | 
			
		||||
            myBaja = new MyBaja();
 | 
			
		||||
            myBaja.setMyUserAccount(Login)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (localStorage.getItem('mitsubishi-t') == 'true') {
 | 
			
		||||
            document.getElementById("rememberme").checked = true;
 | 
			
		||||
            remember = true;
 | 
			
		||||
            $("#account").val(atob(localStorage.getItem('taipei-a')));
 | 
			
		||||
            $("#password").val(atob(localStorage.getItem('taipei-p')));
 | 
			
		||||
            $("#account").val(atob(localStorage.getItem('mitsubishi-a')));
 | 
			
		||||
            $("#password").val(atob(localStorage.getItem('mitsubishi-p')));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            document.getElementById("rememberme").checked = false;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $("#rememberme").click(function () {
 | 
			
		||||
        if (remember) {
 | 
			
		||||
            localStorage.setItem('taipei-t', 'false');
 | 
			
		||||
            localStorage.removeItem('taipei-a');
 | 
			
		||||
            localStorage.removeItem('taipei-p');
 | 
			
		||||
            remember = false;
 | 
			
		||||
        } else {
 | 
			
		||||
            localStorage.setItem('taipei-t', 'true');
 | 
			
		||||
            localStorage.setItem('taipei-a', btoa($("#account").val()));
 | 
			
		||||
            localStorage.setItem('taipei-p', btoa($("#password").val()));
 | 
			
		||||
            remember = true;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
        var loginValidate = $("#login-form").validate({
 | 
			
		||||
            rules: {
 | 
			
		||||
                account: {
 | 
			
		||||
                    required: true,
 | 
			
		||||
                    maxlength: 50,
 | 
			
		||||
                    filterspace: true
 | 
			
		||||
                },
 | 
			
		||||
                password: {
 | 
			
		||||
                    required: true,
 | 
			
		||||
                    maxlength: 50,
 | 
			
		||||
                    filterspace: true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    $("#account").change(function () {
 | 
			
		||||
        if (remember) {
 | 
			
		||||
            localStorage.setItem('taipei-a', btoa($("#account").val()));
 | 
			
		||||
        } else {
 | 
			
		||||
            localStorage.removeItem('taipei-a');
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
        //驗證是否為空白
 | 
			
		||||
        jQuery.validator.addMethod("filterspace", function (value, element) {
 | 
			
		||||
            var str = value;
 | 
			
		||||
            var result = false;
 | 
			
		||||
            if (str.length > 0) {
 | 
			
		||||
                if ($.trim(str) != '') {
 | 
			
		||||
                    result = true;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    result = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
        }, "不可填入空白");
 | 
			
		||||
 | 
			
		||||
    $("#password").change(function () {
 | 
			
		||||
        if (remember) {
 | 
			
		||||
            localStorage.setItem('taipei-p', btoa($("#password").val()));
 | 
			
		||||
        } else {
 | 
			
		||||
            localStorage.removeItem('taipei-p');
 | 
			
		||||
        $("#rememberme").click(function () {
 | 
			
		||||
            if (remember) {
 | 
			
		||||
                localStorage.setItem('mitsubishi-t', 'false');
 | 
			
		||||
                localStorage.removeItem('mitsubishi-a');
 | 
			
		||||
                localStorage.removeItem('mitsubishi-p');
 | 
			
		||||
                remember = false;
 | 
			
		||||
            } else {
 | 
			
		||||
                localStorage.setItem('mitsubishi-t', 'true');
 | 
			
		||||
                localStorage.setItem('mitsubishi-a', btoa($("#account").val()));
 | 
			
		||||
                localStorage.setItem('mitsubishi-p', btoa($("#password").val()));
 | 
			
		||||
                remember = true;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $("#account").change(function () {
 | 
			
		||||
            if (remember) {
 | 
			
		||||
                localStorage.setItem('mitsubishi-a', btoa($("#account").val()));
 | 
			
		||||
            } else {
 | 
			
		||||
                localStorage.removeItem('mitsubishi-a');
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $("#password").change(function () {
 | 
			
		||||
            if (remember) {
 | 
			
		||||
                localStorage.setItem('mitsubishi-p', btoa($("#password").val()));
 | 
			
		||||
            } else {
 | 
			
		||||
                localStorage.removeItem('mitsubishi-p');
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $("#login-form").on("submit", function (e) {
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
    }
 | 
			
		||||
    function Login(account, e) {
 | 
			
		||||
        e ? e.preventDefault() : "";
 | 
			
		||||
        /*if ($("#login-form").valid()) {*/
 | 
			
		||||
        var url = baseApiUrl + "/api/Login/";
 | 
			
		||||
        var send_data = {
 | 
			
		||||
            account: account,
 | 
			
		||||
            password: "rJ2T5Kkj"
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
        if (location.href.indexOf("localhost:5966") != -1) {
 | 
			
		||||
            send_data = {
 | 
			
		||||
                account: $("#account").val(),
 | 
			
		||||
                password: $("#password").val()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            method: "post",
 | 
			
		||||
            url: url,
 | 
			
		||||
            data: JSON.stringify(send_data),
 | 
			
		||||
            async: false,
 | 
			
		||||
            contentType: "application/json; charset=UTF-8",
 | 
			
		||||
            dataType: 'json',
 | 
			
		||||
            success: function (rel) {
 | 
			
		||||
                console.log(rel)
 | 
			
		||||
 | 
			
		||||
                //rel = JSON.stringify(rel);
 | 
			
		||||
                if (rel.code != "0000") {
 | 
			
		||||
                    toast_error(rel.msg || "系統內部發生錯誤,請聯絡系統管理員");
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    toast_ok(rel.msg);
 | 
			
		||||
                    localStorage.setItem('JWT-Authorization', rel.data.token);
 | 
			
		||||
                    location.href = "index.html";
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            error: function (xhr, textStatus, thrownError) {
 | 
			
		||||
                alert(textStatus);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
    //#region 登入表單驗證
 | 
			
		||||
    var loginValidate = $("#login-form").validate({
 | 
			
		||||
        rules: {
 | 
			
		||||
            account: {
 | 
			
		||||
                required: true,
 | 
			
		||||
                maxlength: 50,
 | 
			
		||||
                filterspace: true
 | 
			
		||||
            },
 | 
			
		||||
            password: {
 | 
			
		||||
                required: true,
 | 
			
		||||
                maxlength: 50,
 | 
			
		||||
                filterspace: true
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    //驗證是否為空白
 | 
			
		||||
    jQuery.validator.addMethod("filterspace", function (value, element) {
 | 
			
		||||
        var str = value;
 | 
			
		||||
        var result = false;
 | 
			
		||||
        if (str.length > 0) {
 | 
			
		||||
            if ($.trim(str) != '') {
 | 
			
		||||
                result = true;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                result = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }, "不可填入空白");
 | 
			
		||||
    //#endregion
 | 
			
		||||
 | 
			
		||||
    function Login(e) {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        if ($("#login-form").valid()) {
 | 
			
		||||
            var url = baseApiUrl + "/api/Login/";
 | 
			
		||||
            var send_data = {
 | 
			
		||||
                account: "admin",
 | 
			
		||||
                password: "123456"
 | 
			
		||||
            }
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                method: "post",
 | 
			
		||||
                url: url,
 | 
			
		||||
                data: JSON.stringify(send_data),
 | 
			
		||||
                async: false,
 | 
			
		||||
                contentType:"application/json; charset=UTF-8",
 | 
			
		||||
                dataType: 'json',
 | 
			
		||||
                success: function (rel) {
 | 
			
		||||
                    //rel = JSON.stringify(rel);
 | 
			
		||||
                    if (rel.code != "0000") {
 | 
			
		||||
                        toast_error(rel.msg || "系統內部發生錯誤,請聯絡系統管理員");
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        toast_ok(rel.msg);
 | 
			
		||||
                        localStorage.setItem('JWT-Authorization', rel.data.token);
 | 
			
		||||
                        location.href = "index.html";
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                error: function (xhr, textStatus, thrownError) {
 | 
			
		||||
                    toast_error(textStatus);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user