加入專案檔案。

This commit is contained in:
陳啟峰 2022-10-14 16:08:54 +08:00
parent 8dd1f67562
commit dec698413b
2207 changed files with 2894490 additions and 0 deletions

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>dotnet-AlarmMonitorWorkerService-BB400DAF-C7FE-429A-A172-F3B07F094E0A</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.19" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="3.1.19" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageReference Include="Quartz" Version="3.4.0" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Repository\Repository.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AlarmMonitorWorkerService.Models
{
public class AlarmorionString
{
public string device_number { get; set; }
public string point { get; set; }
public string source_path { get; set; }
public string alarm_timestamp { get; set; }
public string source_name { get; set; }
public string source_msg { get; set; }
}
public class DeviceInfo
{
public string device_number { get; set; }
public string device_disaster_type_text { get; set; }
public string device_name { get; set; }
public string building_name { get; set; }
public string floor_name { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AlarmMonitorWorkerService.Models
{
public class Variable
{
public string System_type { get; set; }
public string System_key { get; set; }
public string system_value { get; set; }
}
public class KeyValue
{
public string Name { get; set; }
public string Value { get; set; }
}
}

View File

@ -0,0 +1,67 @@
using AlarmMonitorWorkerService.Quartz;
using AlarmMonitorWorkerService.Quartz.Jobs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using Repository.BaseRepository.Implement;
using Repository.BaseRepository.Interface;
using Repository.FrontendRepository.Implement;
using Repository.FrontendRepository.Interface;
using Repository.Helper;
using Repository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AlarmMonitorWorkerService
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
IConfiguration configuration = hostContext.Configuration;
#region DBHelper
services.Configure<DBConfig>(configuration.GetSection("DBConfig"));
services.AddTransient<IDatabaseHelper, DatabaseHelper>();
#endregion DBHelper
#region Repository
//services.AddTransient<IBackendRepository, BackendRepository>();
//services.AddTransient<IBackgroundServiceRepository, BackgroundServiceRepository>();
services.AddTransient<IFrontendRepository, FrontendRepository>();
services.AddTransient<IBaseRepository, BaseRepository>();
#endregion Repository
//添加Quartz服務
services.AddTransient<IJobFactory, SingletonJobFactory>();
services.AddTransient<ISchedulerFactory, StdSchedulerFactory>();
services.AddHostedService<QuartzHostedService>();
#region (3)
services.AddSingleton<AlarmMonitorJob>();
services.AddSingleton(
new JobSchedule(jobType: typeof(AlarmMonitorJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:AlarmMonitorJob"))
);
#endregion
}).ConfigureLogging((hostContext, logFactory) => {
IConfiguration configuration = hostContext.Configuration;
//logFactory.AddFile("Logs/log-{Date}.txt");
logFactory.AddFile(configuration.GetValue<string>("LoggerPath") + "/log-{Date}.txt");
});
}
}

View File

@ -0,0 +1,10 @@
{
"profiles": {
"AlarmMonitorWorkerService": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
namespace AlarmMonitorWorkerService.Quartz
{
/// <summary>
/// Job調度中間對象
/// </summary>
public class JobSchedule
{
public JobSchedule(Type jobType, string cronExpression)
{
this.JobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
CronExpression = cronExpression ?? throw new ArgumentNullException(nameof(cronExpression));
}
/// <summary>
/// Job類型
/// </summary>
public Type JobType { get; private set; }
/// <summary>
/// Cron表達式
/// </summary>
public string CronExpression { get; private set; }
/// <summary>
/// Job狀態
/// </summary>
public JobStatus JobStatu { get; set; } = JobStatus.Init;
}
/// <summary>
/// Job運行狀態
/// </summary>
public enum JobStatus : byte
{
[Description("初始化")]
Init = 0,
[Description("運行中")]
Running = 1,
[Description("調度中")]
Scheduling = 2,
[Description("已停止")]
Stopped = 3,
}
}

View File

@ -0,0 +1,211 @@
using AlarmMonitorWorkerService.Models;
using Microsoft.Extensions.Logging;
using Quartz;
using Repository.FrontendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using System.IO;
namespace AlarmMonitorWorkerService.Quartz.Jobs
{
/// <summary>
/// 監控緊急應變畫面是否有開啟
/// </summary>
[DisallowConcurrentExecution]
class AlarmMonitorJob : IJob
{
private const string APP_ID = "WPF ToastNotificaiton Test";
private readonly ILogger<AlarmMonitorJob> logger;
private readonly IFrontendRepository frontendRepository;
public AlarmMonitorJob(
ILogger<AlarmMonitorJob> logger,
IFrontendRepository frontendRepository)
{
this.logger = logger;
this.frontendRepository = frontendRepository;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
logger.LogInformation("【AlarmMonitorJob】【任務開始】");
//找出當前緊急應變的PID
var sqlWatchDog = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'watchDogCongfig'";
var variable = await frontendRepository.GetAllAsync<KeyValue>(sqlWatchDog);
var alarmPID = variable.Where(x => x.Name == "AlarmPID").Select(x => x.Value).FirstOrDefault();
var category = new PerformanceCounterCategory("Process");
var instances = category.GetInstanceNames();
var hasFound = false;
foreach (var instance in instances)
{
try
{
using (var counter = new PerformanceCounter(category.CategoryName,
"ID Process", instance, true))
{
int val = (int)counter.RawValue;
if (val == Convert.ToInt32(alarmPID))
{
hasFound = true;
break;
}
}
}
catch (Exception exception)
{
}
}
var header = string.Empty;
if (!hasFound)
{
header = "請開啟監控頁面";
}
//找出異常的設備
string sql = $@"SELECT
amc.id,
sl.source source_path,
from_unixtime(amc.timestamp/1000,'%Y-%m-%d %H:%i:%s') alarm_timestamp ,
temp_source.source_name,
temp_msg.source_msg
FROM alarmorion_orionalarmrecord amc
JOIN (
SELECT
MAX(amc.alarm) ad,
m.source
FROM alarmorion_orionalarmsourceorder amc
JOIN (
SELECT * FROM alarmorion_orionalarmsource a
WHERE substring(a.source,23,5) ='Arena'
) m ON amc.alarmSource = m.id
GROUP BY m.source
) sl ON amc.id = sl.ad
JOIN(
SELECT
val.alarm ,
val.value AS source_name
FROM alarmorion_orionalarmfacetvalue val
JOIN alarmorion_orionalarmfacetname nam ON val.facetName = nam.id AND nam.facetName = 'sourceName'
) temp_source ON amc.id = temp_source.alarm
JOIN(
SELECT
val.alarm,
val.value AS source_msg
FROM alarmorion_orionalarmfacetvalue val
JOIN alarmorion_orionalarmfacetname nam ON val.facetName = nam.id AND nam.facetName = 'msgText'
) temp_msg ON amc.id = temp_msg.alarm
WHERE amc.sourceState = 1";
var alarms = await frontendRepository.GetAllAsync<AlarmorionString>(sql);
//組出device_number
List<string> tempDeviceNumbers = new List<string>();
foreach (var alarm in alarms)
{
var alarmSplit = alarm.source_path.Split("|");
var deviceSplit = alarmSplit[alarmSplit.Length - 1].Split("/");
var device_number = deviceSplit[deviceSplit.Length - 3];
var point = deviceSplit[deviceSplit.Length - 2];
alarm.device_number = device_number.Replace("$3", "");
alarm.point = point;
tempDeviceNumbers.Add(device_number);
}
//找出所有設備相關資訊
var sql_device = $@"SELECT
d.device_number,
d.full_name AS device_name,
b.full_name AS building_name,
f.full_name AS floor_name,
(SELECT
v.system_key
FROM device_disaster dd
JOIN variable v ON v.deleted = 0 AND v.system_type = 'disaster' AND v.system_value = dd.device_system_value
WHERE dd.device_guid = d.device_guid
) AS Device_disaster_type_text
FROM device d
JOIN building b ON b.deleted = 0 AND d.building_guid = b.building_guid
JOIN floor f ON f.deleted = 0 AND d.floor_guid = f.floor_guid
WHERE d.deleted = 0 AND d.device_number IN @device_numbers";
var deviceInfos = await frontendRepository.GetAllAsync<DeviceInfo>(sql_device, new { device_numbers = tempDeviceNumbers.Distinct().ToList() });
var alarmFormat = @"{0}{1} {2} {3} {4} {5}觸發";
List<string> alarmMsg = new List<string>();
foreach (var alarm in alarms)
{
var selected_deviceinfo = deviceInfos.Where(x => x.device_number == alarm.device_number).FirstOrDefault();
if (selected_deviceinfo != null)
{
alarmMsg.Add(string.Format(alarmFormat,
selected_deviceinfo.device_disaster_type_text,
alarm.alarm_timestamp,
selected_deviceinfo.building_name,
selected_deviceinfo.floor_name,
selected_deviceinfo.device_name,
alarm.point));
}
}
GenerateToast("IBMS緊急應變通知", null, header, "", string.Join("\n", alarmMsg));
logger.LogInformation("【AlarmMonitorJob】【任務完成】");
}
catch (Exception exception)
{
logger.LogError("【AlarmMonitorJob】【任務失敗】");
logger.LogError("【AlarmMonitorJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
public void GenerateToast(string appid, string imageFullPath, string h1, string h2, string p1)
{
try
{
var template = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04);
var textNodes = template.GetElementsByTagName("text");
textNodes[0].AppendChild(template.CreateTextNode(h1));
textNodes[1].AppendChild(template.CreateTextNode(h2));
textNodes[2].AppendChild(template.CreateTextNode(p1));
//if (File.Exists(imageFullPath))
//{
// XmlNodeList toastImageElements = template.GetElementsByTagName("image");
// ((XmlElement)toastImageElements[0]).SetAttribute("src", imageFullPath);
//}
IXmlNode toastNode = template.SelectSingleNode("/toast");
((XmlElement)toastNode).SetAttribute("duration", "long");
var notifier = ToastNotificationManager.CreateToastNotifier(appid);
var notification = new ToastNotification(template);
notifier.Show(notification);
}
catch (Exception)
{
// Ignore
}
}
}
}

View File

@ -0,0 +1,71 @@
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AlarmMonitorWorkerService.Quartz
{
public class QuartzHostedService : IHostedService
{
private readonly ISchedulerFactory _schedulerFactory;
private readonly IJobFactory _jobFactory;
private readonly IEnumerable<JobSchedule> _jobSchedules;
public QuartzHostedService(ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IEnumerable<JobSchedule> jobSchedules)
{
_schedulerFactory = schedulerFactory ?? throw new ArgumentNullException(nameof(schedulerFactory));
_jobFactory = jobFactory ?? throw new ArgumentNullException(nameof(jobFactory));
_jobSchedules = jobSchedules ?? throw new ArgumentNullException(nameof(jobSchedules));
}
public IScheduler Scheduler { get; set; }
public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
Scheduler.JobFactory = _jobFactory;
foreach (var jobSchedule in _jobSchedules)
{
var job = CreateJob(jobSchedule);
var trigger = CreateTrigger(jobSchedule);
await Scheduler.ScheduleJob(job, trigger, cancellationToken);
jobSchedule.JobStatu = JobStatus.Scheduling;
}
await Scheduler.Start(cancellationToken);
foreach (var jobSchedule in _jobSchedules)
{
jobSchedule.JobStatu = JobStatus.Running;
}
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
foreach (var jobSchedule in _jobSchedules)
{
jobSchedule.JobStatu = JobStatus.Stopped;
}
}
private static IJobDetail CreateJob(JobSchedule schedule)
{
var jobType = schedule.JobType;
return JobBuilder
.Create(jobType)
.WithIdentity(jobType.FullName)
.WithDescription(jobType.Name)
.Build();
}
private static ITrigger CreateTrigger(JobSchedule schedule)
{
return TriggerBuilder
.Create()
.WithIdentity($"{schedule.JobType.FullName}.trigger")
.WithCronSchedule(schedule.CronExpression)
.WithDescription(schedule.CronExpression)
.Build();
}
}
}

View File

@ -0,0 +1,26 @@
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Text;
namespace AlarmMonitorWorkerService.Quartz
{
public class SingletonJobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;
public SingletonJobFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
}
public void ReturnJob(IJob job)
{
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AlarmMonitorWorkerService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
}

View File

@ -0,0 +1,28 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"BackgroundServiceCron": {
"AlarmMonitorJob": "0/3 * * * * ?"
},
"DBConfig": {
//"MySqlDBConfig": {
// "Server": "TNi6aupYHPZT8ZU177KTKw==", //172.16.220.251
// "Port": "mkF51jVbg40V5K5eTh2Ckw==",
// "Database": "VvfWH/59gQguY2eA2xBCug==",
// "Root": "IV8Ec1Ng2AWAnkBafXy2kg==",
// "Password": "Jue6jMFRi11meN6xbdKwDA=="
//},
"MySqlDBConfig": {
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
"Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
},
}
}

View File

@ -0,0 +1,28 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"BackgroundServiceCron": {
"AlarmMonitorJob": "0/3 * * * * ?"
},
"DBConfig": {
"MySqlDBConfig": {
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
"Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
}
//"MySqlDBConfig": {
// "Server": "ueFp+VFb200lhh1Uctc97WH0/tX6tfXYU2v1oxCWuuM=", //greencloud.fic.com.tw
// "Port": "mkF51jVbg40V5K5eTh2Ckw==",
// "Database": "VvfWH/59gQguY2eA2xBCug==",
// "Root": "+plVKQ+enAqt7BYV2uMQng==",
// "Password": "tWzphRxS8piHZiHpxRpzrg=="
//},
}
}

View File

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "6.0.0",
"commands": [
"dotnet-ef"
]
}
}
}

View File

@ -0,0 +1,128 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
namespace Backend.ApiControllers
{
public class DeviceApiController : MyBaseApiController<DeviceApiController>
{
private readonly IBackendRepository backendRepository;
public DeviceApiController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
/// <summary>
/// 修改設備名稱
/// </summary>
/// <param name="change"></param>
/// <returns></returns>
[HttpPost]
[Route("api/Device/SaveChangeName")]
public async Task<ActionResult<ApiResult<string>>> SaveChangeName(ChangeName change)
{
ApiResult<string> apiResult = new ApiResult<string>();
if (!jwtlife)
{
apiResult.Code = "5000";
return BadRequest(apiResult);
}
try
{
if (change.ChooseTable == 0)
{
//一般設備
var GetOne = await backendRepository.GetOneAsync<Device>("device", $" device_number = '{change.TagName}'");
if (GetOne == null)
{
apiResult.Data = "查無資料";
apiResult.Code = "0001";
}
else
{
//修改設備名稱
Dictionary<string, object> ChangeN = new Dictionary<string, object>();
ChangeN = new Dictionary<string, object>()
{
{ "@full_name", change.ChangeN},
{ "@updated_at",DateTime.Now},
};
await backendRepository.UpdateOneByCustomTable(ChangeN, "device", $" device_number = '{change.TagName}'");
//記錄使用者操作紀錄
Dictionary<string, object> userOperatorLog = new Dictionary<string, object>()
{
{ "@user_guid", myUser.userinfo_guid },
{ "@operation_type", 1 }, //1名稱修改
{ "@building_guid", GetOne.Building_guid },
{ "@main_system_guid", GetOne.Main_system_guid },
{ "@sub_system_guid", GetOne.Sub_system_guid },
{ "@floor_guid", GetOne.Floor_guid },
{ "@device_guid", GetOne.Device_guid },
{ "@action_name", "修改名稱" },
{ "@parameter", JsonConvert.SerializeObject(change) },
};
await backendRepository.AddOneByCustomTable(userOperatorLog, "operation_log");
apiResult.Data = "更改成功";
apiResult.Code = "0000";
}
}
else
{
//燈控設備
var GetOne = await backendRepository.GetOneAsync<string>("device_master", $" device_master_number = '{change.TagName}'");
if (GetOne == null)
{
apiResult.Data = "查無資料";
apiResult.Code = "0001";
}
else
{
Dictionary<string, object> ChangeN = new Dictionary<string, object>();
ChangeN = new Dictionary<string, object>()
{
{ "@device_master_full_name", change.ChangeN},
{ "@updated_at",DateTime.Now},
};
await backendRepository.UpdateOneByCustomTable(ChangeN, "device_master", $" device_master_number = '{change.TagName}'");
////記錄使用者操作紀錄
//Dictionary<string, object> userOperatorLog = new Dictionary<string, object>()
//{
// { "@user_guid", myUser },
// { "@operation_type", 1 }, //1名稱修改
// { "@building_guid", GetOne.Building_guid },
// { "@main_system_guid", GetOne.Main_system_guid },
// { "@sub_system_guid", GetOne.Sub_system_guid },
// { "@floor_guid", GetOne.Floor_guid },
// { "@device_guid", GetOne.Device_guid },
// { "@action_name", "修改名稱" },
// { "@parameter", JsonConvert.SerializeObject(change) },
//};
//await backendRepository.AddOneByCustomTable(userOperatorLog, "operation_log");
apiResult.Data = "更改成功";
apiResult.Code = "0000";
}
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
return Ok(apiResult);
}
return Ok(apiResult);
}
}
}

View File

@ -0,0 +1,81 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Repository.BackendRepository.Interface;
using Repository.BaseRepository.Interface;
using Repository.FrontendRepository.Interface;
using Repository.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Backend.Models;
using Backend.Jwt;
namespace Backend.ApiControllers
{
public class MyBaseApiController<T> : Controller where T : MyBaseApiController<T>
{
private ILogger<T> _logger;
protected ILogger<T> Logger => _logger ?? (_logger = HttpContext?.RequestServices.GetService<ILogger<T>>());
private IJwtHelpers jwt => HttpContext?.RequestServices.GetService<IJwtHelpers>();
//private IDatabaseHelper qqwt => HttpContext?.RequestServices.GetService<IDatabaseHelper>();
public MyBaseApiController() { }
protected JwtGet myUser;
protected string jwt_str = null;
protected bool jwtlife = true;
public string controllerName;
public string actionName;
//public ErrorCode errorCode = new ErrorCode();
[Authorize]
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
controllerName = ControllerContext.RouteData.Values["controller"].ToString(); //controller名稱
actionName = ControllerContext.RouteData.Values["action"].ToString(); //action名稱
var ctx = filterContext.HttpContext;
ctx.Response.Headers.Add("Access-Control-Allow-Origin", "*");
ctx.Response.Headers.Add("Access-Control-Allow-Headers", "*");
ctx.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
EDFunction edFunction = new EDFunction();
var a = User.Claims.Select(p => new { Type = p.Type, Value = p.Value }).ToList();
myUser = new JwtGet()
{
account = User.Claims.Where(a => a.Type == "account").Select(e => e.Value).FirstOrDefault(),
email = User.Claims.Where(a => a.Type == "email").Select(e => e.Value).FirstOrDefault(),
full_name = User.Claims.Where(a => a.Type == "full_name").Select(e => e.Value).FirstOrDefault(),
exp = User.Claims.Where(a => a.Type == "exp").Select(e => Convert.ToInt32(e.Value)).FirstOrDefault(),
nbf = User.Claims.Where(a => a.Type == "nbf").Select(e => Convert.ToInt32(e.Value)).FirstOrDefault(),
userinfo_guid = User.Claims.Where(a => a.Type == "userinfo_guid").Select(e => e.Value).FirstOrDefault(),
};
if (myUser.exp == 0)
{
jwt_str = "Jwt Token不合法";
jwtlife = false;
}
else
{
if (myUser.exp <= DateTime.Now.AddHours(-8).AddMinutes(10).Subtract(new DateTime(1970, 1, 1)).TotalSeconds)
{
jwtlife = true;
JwtLogin jwtLoing = new JwtLogin()
{
account = myUser.account,
email = myUser.email,
full_name = myUser.full_name,
userinfo_guid = myUser.userinfo_guid
};
jwt_str = jwt.GenerateToken(jwtLoing).token;
}
}
base.OnActionExecuting(filterContext);
}
}
}

45
Backend/Backend.csproj Normal file
View File

@ -0,0 +1,45 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>8a5f6c4d-4a50-40fa-aacf-a238bb8fb733</UserSecretsId>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
</PropertyGroup>
<ItemGroup>
<Compile Remove="wwwroot\lib\jquery.lazy-master\**" />
<Content Remove="wwwroot\lib\jquery.lazy-master\**" />
<EmbeddedResource Remove="wwwroot\lib\jquery.lazy-master\**" />
<None Remove="wwwroot\lib\jquery.lazy-master\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Controllers\NpoiMemoryStream.cs" />
</ItemGroup>
<ItemGroup>
<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" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NPOI" Version="2.5.5" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Repository\Repository.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Repository\Repository.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\upload\floor_map\" />
<Folder Include="wwwroot\upload\device_icon\" />
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
</Project>

View File

@ -0,0 +1,588 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using System.Transactions;
namespace Backend.Controllers
{
public class BuildInfoController : MybaseController<BuildInfoController>
{
private readonly IBackendRepository backendRepository;
private string mapFileSaveAsPath = "";
public BuildInfoController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
mapFileSaveAsPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "upload", "floor_map");
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// 區域基本資料列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<BuildInfo>>> BuildInfoList()
{
ApiResult<List<BuildInfo>> apiResult = new ApiResult<List<BuildInfo>>();
List<BuildInfo> buildInfo = new List<BuildInfo>();
try
{
var sqlString = @$"SELECT A.priority, A.building_guid, A.full_name, A.ip_address, A.ip_port, (SELECT COUNT(*) FROM floor f WHERE f.deleted = 0 AND f.building_guid = A.building_guid) AS 'floorNum', A.created_at
FROM building A
WHERE A.deleted = 0
ORDER BY A.priority ASC, A.created_at DESC";
buildInfo = await backendRepository.GetAllAsync<BuildInfo>(sqlString);
apiResult.Code = "0000";
apiResult.Data = buildInfo;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 新增 / 修改 區域基本資料
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> SaveBuildInfo(BuildInfo post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
//判斷監控主機IP是否重複
var judgeIPAddressRepeat = true;
var sWhere = $@"deleted = 0 AND ip_address = @ip_address AND ip_port = @ip_port AND building_guid != @building_guid";
var buildInfos = await backendRepository.GetAllAsync<BuildInfo>("building", sWhere, new { ip_address = post.Ip_address, ip_port = post.Ip_port, building_guid = post.Building_guid });
if (buildInfos.Count == 0)
{
judgeIPAddressRepeat = false;
}
if (!judgeIPAddressRepeat)
{
//新增
if (post.Building_guid == "0")
{
//產生一組GUID
var guid = Guid.NewGuid(); //大樓GUID
//抓取當前的Priority
var current_priority = await backendRepository.GetCurrentPriority("building");
Dictionary<string, object> building = new Dictionary<string, object>();
building = new Dictionary<string, object>()
{
{ "@building_guid", guid},
{ "@full_name", post.Full_name},
{ "@ip_address", post.Ip_address},
{ "@ip_port", post.Ip_port},
{ "@priority", current_priority + 1},
{ "@created_by", myUserInfo.Userinfo_guid}
};
await backendRepository.AddOneByCustomTable(building, "building");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
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},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
};
await backendRepository.UpdateOneByCustomTable(building, "building", "building_guid='" + post.Building_guid + "'");
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
}
else
{
apiResult.Code = "0001";
apiResult.Msg = "監控主機IP不可重複";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> DeleteOneBuild(string guid)
{
var apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = @Deleted AND building_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var buildInfo = await backendRepository.GetOneAsync<BuildInfo>("building", sWhere, param);
if (buildInfo == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該區域資料";
return apiResult;
}
//檢查是否有未刪除的區域選單
var sbuildMenuWhere = $@"building_guid = @Guid";
var buildMenus = await backendRepository.GetAllAsync<BuildMenu>("building_menu", sbuildMenuWhere, new { Guid = guid });
if (buildMenus.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "區域選單中尚有選單正在使用該棟別,故無法刪除";
return apiResult;
}
//檢查底下是否有未刪除的樓層
var sfloorWhere = $@"deleted = 0 AND building_guid = @Guid";
var floors = await backendRepository.GetAllAsync<BuildFloor>("floor", sfloorWhere, new { Guid = guid });
if (floors.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "樓層設定中尚有以下樓層正在使用該棟別,故無法刪除";
apiResult.Data = string.Join("<br>", floors.Select(x => x.Full_name).ToList());
return apiResult;
}
await backendRepository.DeleteOne(guid, "building", "building_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "building_guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 修改棟別區域排列順序
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<string>>> ChangeBuildInfoPriority(PostBuildInfoPriority post)
{
ApiResult<List<string>> apiResult = new ApiResult<List<string>>();
try
{
List<Dictionary<string, object>> building_priorities = new List<Dictionary<string, object>>();
if (post.BuildInfoPriorities != null)
{
foreach (var building_priority in post.BuildInfoPriorities)
{
Dictionary<string, object> building_priority_dic = new Dictionary<string, object>();
building_priority_dic = new Dictionary<string, object>()
{
{ "building_guid", building_priority.Building_guid},
{ "@priority", building_priority.Priority},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
};
building_priorities.Add(building_priority_dic);
}
var sql = $@"UPDATE building SET priority = @priority, updated_by = @updated_by, updated_at=@updated_at WHERE building_guid = @building_guid";
await backendRepository.ExecuteSql(sql, building_priorities);
#region
await backendRepository.ManualInsertBackgroundServiceTask("", "", "building", "update_list", building_priorities);
#endregion
}
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 樓層列表
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<BuildFloor>>> BuildFloorList(string BuildGuid)
{
ApiResult<List<BuildFloor>> apiResult = new ApiResult<List<BuildFloor>>();
List<BuildFloor> buildInfo = new List<BuildFloor>();
try
{
var sqlString = @$"SELECT A.floor_guid, A.full_name, InitMapName + '.svg' AS 'initMapName', A.priority, A.created_at
FROM floor A
WHERE deleted = @deleted
AND A.building_guid = @building_guid
ORDER BY A.priority ASC";
buildInfo = await backendRepository.GetAllAsync<BuildFloor>(sqlString, new { deleted = 0, building_guid = BuildGuid });
apiResult.Code = "0000";
apiResult.Data = buildInfo;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 取得單一樓層設定
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<BuildFloor>> GetOneBuildFloor(string guid)
{
ApiResult<BuildFloor> apiResult = new ApiResult<BuildFloor>();
try
{
string sWhere = @$"deleted = @Deleted AND floor_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var buildFloor = await backendRepository.GetOneAsync<BuildFloor>("floor", sWhere, param);
if (!string.IsNullOrEmpty(buildFloor.InitMapName))
{
buildFloor.MapUrl = "/upload/floor_map/" + buildFloor.Floor_guid + ".svg";
}
apiResult.Code = "0000";
apiResult.Data = buildFloor;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 新增 / 修改 樓層設定
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> SaveBuildFloor([FromForm] BuildFloor post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = @Deleted AND floor_guid = @Guid";
object param = new { Deleted = 0, Guid = post.Floor_guid };
var buildFloor = await backendRepository.GetOneAsync<BuildFloor>("floor", sWhere, param);
if (buildFloor == null)
{
//新增
//產生一組GUID
var guid = Guid.NewGuid();
var floor_map_guid = Guid.NewGuid();
//抓取當前的Priority
var current_priority = await backendRepository.GetCurrentPriority("floor", "deleted = 0 AND building_guid = '" + post.Building_guid + "'");
Dictionary<string, object> floor = new Dictionary<string, object>();
floor = new Dictionary<string, object>()
{
{ "@floor_guid", guid},
{ "@building_guid", post.Building_guid},
{ "@full_name", post.Full_name},
{ "@InitMapName", post.InitMapName},
{ "@floor_map_name", floor_map_guid},
{ "@priority", current_priority + 1},
{ "@created_by", myUserInfo.Userinfo_guid}
};
await backendRepository.AddOneByCustomTable(floor, "floor");
if (post.MapFile != null)
{
var split = post.MapFile.FileName.Split(".");
var fileName = floor_map_guid + "." + split[split.Length - 1];
var fullPath = Path.Combine(mapFileSaveAsPath, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
post.MapFile.CopyTo(stream);
}
}
#region
List<Repository.Models.FileInfo> fileInfos = new List<Repository.Models.FileInfo>();
if (post.MapFile != null)
{
var split = post.MapFile.FileName.Split(".");
var fileName = floor_map_guid + "." + split[split.Length - 1];
var fullPath = Path.Combine(mapFileSaveAsPath, fileName);
Repository.Models.FileInfo fileInfo = new Repository.Models.FileInfo();
fileInfo.Folder = "floor_map";
fileInfo.OriginalFileName = null;
fileInfo.FileName = fileName;
fileInfo.File = fullPath;
fileInfos.Add(fileInfo);
await backendRepository.ManualInsertFileBackgroundServiceTask("", post.Building_guid, "floor", fileInfos);
}
#endregion
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else //修改
{
Dictionary<string, object> floor = new Dictionary<string, object>();
floor = new Dictionary<string, object>()
{
{ "@full_name", post.Full_name},
{ "@InitMapName", post.InitMapName},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
};
await backendRepository.UpdateOneByCustomTable(floor, "floor", "floor_guid='" + post.Floor_guid + "'");
var floor_map_guid = Guid.NewGuid();
if (post.MapFile != null)
{
//刪除原本檔案
FolderFunction folderFunction = new FolderFunction();
folderFunction.DeleteFile(Path.Combine(mapFileSaveAsPath, buildFloor.Floor_map_name + ".svg"));
Dictionary<string, object> floor_map_dic = new Dictionary<string, object>();
floor_map_dic = new Dictionary<string, object>()
{
{ "@floor_map_name", floor_map_guid},
};
await backendRepository.UpdateOneByCustomTable(floor_map_dic, "floor", "floor_guid='" + post.Floor_guid + "'");
var split = post.MapFile.FileName.Split(".");
var fileName = floor_map_guid + "." + split[split.Length - 1];
var fullPath = Path.Combine(mapFileSaveAsPath, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
post.MapFile.CopyTo(stream);
}
}
#region
List<Repository.Models.FileInfo> fileInfos = new List<Repository.Models.FileInfo>();
if (post.MapFile != null)
{
var split = post.MapFile.FileName.Split(".");
var fileName = floor_map_guid + "." + split[split.Length - 1];
var fullPath = Path.Combine(mapFileSaveAsPath, fileName);
Repository.Models.FileInfo fileInfo = new Repository.Models.FileInfo();
fileInfo.Folder = "floor_map";
fileInfo.OriginalFileName = buildFloor.Floor_map_name + ".svg";
fileInfo.FileName = fileName;
fileInfo.File = fullPath;
fileInfos.Add(fileInfo);
}
await backendRepository.ManualInsertFileBackgroundServiceTask("", post.Building_guid, "floor", fileInfos);
#endregion
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 修改樓層排列順序
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<string>>> ChangeFloorPriority(PostFloorPriority post)
{
ApiResult<List<string>> apiResult = new ApiResult<List<string>>();
try
{
List<Dictionary<string, object>> floor_priorities = new List<Dictionary<string, object>>();
if (post.FloorPriorities != null)
{
foreach (var floor_priority in post.FloorPriorities)
{
Dictionary<string, object> floor_priority_dic = new Dictionary<string, object>();
floor_priority_dic = new Dictionary<string, object>()
{
{ "@floor_guid", floor_priority.Floor_guid},
{ "@priority", floor_priority.Priority},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
};
floor_priorities.Add(floor_priority_dic);
}
var sql = $@"UPDATE floor SET priority = @priority, updated_by = @updated_by, updated_at=@updated_at WHERE floor_guid = @floor_guid";
await backendRepository.ExecuteSql(sql, floor_priorities);
#region
await backendRepository.ManualInsertBackgroundServiceTask("", "", "floor", "update_list", floor_priorities);
#endregion
}
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 刪除單一樓層設定
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> DeleteOneFloor(string guid)
{
var apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = @Deleted AND floor_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var buildFloor = await backendRepository.GetOneAsync<BuildFloor>("floor", sWhere, param);
if (buildFloor == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該樓層設定";
return apiResult;
}
//判斷區域選單是否還有使用該樓層
var sub_system_where = $@"SELECT
CONCAT(b.full_name, ' - ', ms.full_name, ' - ', ss.full_name)
FROM (
SELECT
ssf.building_guid,
ssf.main_system_guid,
ssf.sub_system_guid
FROM sub_system_floor ssf
WHERE ssf.deleted = 0 AND floor_guid = @Guid
) ssf
LEFT JOIN building b ON ssf.building_guid = b.building_guid AND b.deleted = 0
LEFT JOIN main_system ms ON ssf.main_system_guid = ms.main_system_guid AND ms.deleted = 0
LEFT JOIN sub_system ss ON ssf.sub_system_guid = ss.sub_system_guid AND ss.deleted = 0";
var sub_system_floors = await backendRepository.GetAllAsync<string>(sub_system_where, new { Guid = guid });
if (sub_system_floors.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "區域選單中尚有以下選單正在使用該樓層,故無法刪除";
apiResult.Data = string.Join("<br>", sub_system_floors);
return apiResult;
}
await backendRepository.DeleteOne(guid, "floor", "floor_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "floor_guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
}
}

View File

@ -0,0 +1,557 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class BuildMenuController : MybaseController<BuildMenuController>
{
private readonly IBackendRepository backendRepository;
public BuildMenuController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> BuildInfoList()
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> KeyValue = new List<KeyValue>();
try
{
var sqlString = @$"select building_guid as Value, full_name as Name from building a where a.deleted = 0 and a.status = 0 ORDER BY A.priority ASC, A.created_at DESC";
KeyValue = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = KeyValue;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> MainListBybuild(string build)
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> KeyValue = new List<KeyValue>();
try
{
var sqlString = @$"select ms.main_system_guid value, ms.full_name name from (select main_system_guid from building_menu bm where bm.building_guid = '{build}' group by bm.main_system_guid ) bm left join main_system ms on ms.main_system_guid = bm.main_system_guid ORDER BY ms.priority ASC";
KeyValue = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = KeyValue;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> MainList()
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> KeyValue = new List<KeyValue>();
try
{
var sqlString = @$"select ms.full_name Name,ms.main_system_guid Value from main_system ms where ms.deleted = 0 and ms.status = 0 ORDER BY ms.priority ASC";
KeyValue = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = KeyValue;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> SubListNotAdd(SubListIn post)
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> KeyValue = new List<KeyValue>();
try
{
var sqlString = @$"select
ss.sub_system_guid value,ss.full_name name
from sub_system ss
left join (
select * from building_menu bm where bm.building_guid = '{post.build}') bm
on ss.sub_system_guid = bm.sub_system_guid
where bm.sub_system_guid is null and ss.deleted = 0 and ss.status = 0 and ss.main_system_guid = @guid ORDER BY ss.priority ASC, ss.created_at DESC";
KeyValue = await backendRepository.GetAllAsync<KeyValue>(sqlString, new { guid = post.main });
apiResult.Code = "0000";
apiResult.Data = KeyValue;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> SavebuildMenuModal(BuildMenu buildMenu)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
var get = await backendRepository.GetOneAsync<BuildMenu>("building_menu", $"building_guid = '{buildMenu.building_guid}' and main_system_guid = '{buildMenu.main_system_guid}' and sub_system_guid = '{buildMenu.sub_system_guid}'");
if (get == null)
{
var dictionary = new Dictionary<string, object>()
{
{"@building_guid", buildMenu.building_guid},
{"@main_system_guid",buildMenu.main_system_guid },
{"@sub_system_guid", buildMenu.sub_system_guid},
{"@drawing",buildMenu.drawing },
{"@created_by",myUserInfo.Userinfo_guid },
{"@planimetric_click",buildMenu.planimetric_click}
};
if (buildMenu.drawing == 2)
{
if (buildMenu.system_url != null && buildMenu.system_url.CompareTo("http://") < 0 && buildMenu.system_url.CompareTo("https://") < 0)
{
//未包含http || https 抓該棟ip + port
var building_where = @"deleted = 0 AND building_guid = @Building_guid";
var building = await backendRepository.GetOneAsync<BuildInfo>("building", building_where, new { Building_guid = buildMenu.building_guid });
buildMenu.system_url = string.Format("http://{0}:{1}{2}", building.Ip_address, building.Ip_port, buildMenu.system_url);
}
dictionary.Add("@system_url", buildMenu.system_url);
}
else if (buildMenu.drawing == 4)
{
if (buildMenu.system_url != null && buildMenu.system_url.CompareTo("http://") < 0 && buildMenu.system_url.CompareTo("https://") < 0)
{
//未包含http || https 抓該棟ip + port
var building_where = @"deleted = 0 AND building_guid = @Building_guid";
var building = await backendRepository.GetOneAsync<BuildInfo>("building", building_where, new { Building_guid = buildMenu.building_guid });
buildMenu.system_url = string.Format("http://{0}:{1}{2}", building.Ip_address, building.Ip_port, buildMenu.system_url);
}
dictionary.Add("@riser_diagram_url", buildMenu.riser_diagram_url);
dictionary.Add("@icon_click", buildMenu.icon_click);
dictionary.Add("@icon_click_url", buildMenu.icon_click_url);
dictionary.Add("@icon_click_url_width", buildMenu.icon_click_url_width);
dictionary.Add("@icon_click_url_height", buildMenu.icon_click_url_height);
}
else if (buildMenu.drawing == 1)
{
dictionary.Add("@planimetric_floor_guid", buildMenu.planimetric_floor_guid);
}
await backendRepository.AddOneByCustomTable(dictionary, "building_menu");
var max = await backendRepository.GetOneAsync<int>("select Max(CONVERT(int,SUBSTRING(AuthCode,2,5))) AuthCode from auth_page ap where ap.AuthCode like 'F%'");
var page = await backendRepository.GetOneAsync<Auth_page>($"select ss.full_name SubName,ms.full_name MainName from sub_system ss left join main_system ms on ms.main_system_guid = ss.main_system_guid where ss.sub_system_guid = '{buildMenu.sub_system_guid}' and ms.main_system_guid = '{buildMenu.main_system_guid}'");
var pagedictionary = new Dictionary<string, object>()
{
{"@AuthCode", "F" +(max+1).ToString() },
{"@AuthType", 1 },
{"@MainName", page.MainName},
{"@SubName",page.SubName},
{"@building_guid",buildMenu.building_guid},
{"@ShowView",buildMenu.sub_system_guid}
};
await backendRepository.AddOneByCustomTable(pagedictionary, "auth_page");
await backendRepository.ExecuteSql(@"DELETE FROM auth_page
WHERE auth_page.AuthCode like 'F%';
INSERT INTO auth_page (AuthCode,AuthType,MainName,SubName,building_guid,ShowView)
SELECT 'F' + CONVERT(varchar,ROW_NUMBER() OVER(ORDER BY bm.building_guid ASC)) AuthCode,'1' AuthType,ms.full_name MainName,ss.full_name SubName,bm.building_guid,bm.sub_system_guid ShowView FROM building_menu bm
left join main_system ms on ms.main_system_guid = bm.main_system_guid
left join sub_system ss on ss.sub_system_guid = bm.sub_system_guid");
await backendRepository.ExecuteSql(@"delete a from role_auth a join role b on a.role_guid = b.role_guid where b.layer = 0;
INSERT INTO role_auth (role_guid,AuthCode,created_by)
SELECT r.role_guid,ap.AuthCode,'0' created_by FROM auth_page ap,role r
WHERE r.layer = 0;");
#region
var sql = $@"SELECT ra.* FROM role_auth ra join role r on ra.role_guid = r.role_guid where r.layer = 0";
var role_auths = await backendRepository.GetAllAsync<RoleAuthList>(sql);
List<Dictionary<string, object>> role_auth_dicts = new List<Dictionary<string, object>>();
foreach (var role_auth in role_auths)
{
Dictionary<string, object> role_auth_dict = new Dictionary<string, object>()
{
{ "role_guid", role_auth.Role_guid},
{ "@AuthCode", role_auth.AuthCode},
};
role_auth_dicts.Add(role_auth_dict);
}
await backendRepository.ManualInsertBackgroundServiceTask("", "", "role_auth", "purge_specify_insert", role_auth_dicts);
#endregion
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
else
{
var dictionary = new Dictionary<string, object>()
{
{"@drawing",buildMenu.drawing },
{"@updated_by",myUserInfo.Userinfo_guid },
{"@updated_at",DateTime.Now },
{"@planimetric_click",buildMenu.planimetric_click}
};
if (buildMenu.drawing == 2)
{
if (buildMenu.system_url != null && buildMenu.system_url.CompareTo("http://") < 0 && buildMenu.system_url.CompareTo("https://") < 0)
{
//未包含http || https 抓該棟ip + port
var building_where = @"deleted = 0 AND building_guid = @Building_guid";
var building = await backendRepository.GetOneAsync<BuildInfo>("building", building_where, new { Building_guid = buildMenu.building_guid });
buildMenu.system_url = string.Format("http://{0}:{1}{2}", building.Ip_address, building.Ip_port, buildMenu.system_url);
}
dictionary.Add("@system_url", buildMenu.system_url);
}
else if (buildMenu.drawing == 4)
{
if (buildMenu.system_url != null && buildMenu.system_url.CompareTo("http://") < 0 && buildMenu.system_url.CompareTo("https://") < 0)
{
//未包含http || https 抓該棟ip + port
var building_where = @"deleted = 0 AND building_guid = @Building_guid";
var building = await backendRepository.GetOneAsync<BuildInfo>("building", building_where, new { Building_guid = buildMenu.building_guid });
buildMenu.system_url = string.Format("http://{0}:{1}{2}", building.Ip_address, building.Ip_port, buildMenu.system_url);
}
dictionary.Add("@riser_diagram_url", buildMenu.riser_diagram_url);
dictionary.Add("@icon_click", buildMenu.icon_click);
dictionary.Add("@icon_click_url", buildMenu.icon_click_url);
dictionary.Add("@icon_click_url_width", buildMenu.icon_click_url_width);
dictionary.Add("@icon_click_url_height", buildMenu.icon_click_url_height);
}
else if (buildMenu.drawing == 1)
{
dictionary.Add("@planimetric_floor_guid", buildMenu.planimetric_floor_guid);
}
await backendRepository.UpdateOneByCustomTable(dictionary, "building_menu", $"building_guid = '{buildMenu.building_guid}' and main_system_guid = '{buildMenu.main_system_guid}' and sub_system_guid = '{buildMenu.sub_system_guid}'");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(buildMenu);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ActionResult> BuildMenuTable(BuildMenuTablePost post)
{
List<BuildMenuTable> buildMenuTables = new List<BuildMenuTable>();
ApiResult<List<BuildMenuTable>> apiResult = new ApiResult<List<BuildMenuTable>>();
try
{
buildMenuTables = await backendRepository.GetAllAsync<BuildMenuTable>($@"select bm.*,
case drawing when 1 then '' when 2 then '' when 4 then '' end drawing_name,
case icon_click when 1 then '開' when 0 then '關' end icon_click_name,
case planimetric_click when 1 then '開' when 0 then '關' end planimetric_click_name,
ms.full_name main_system_guid_name, ss.full_name sub_system_guid_name,ff.full_name floor_guid_name
from building_menu bm
left join main_system ms on ms.main_system_guid = bm.main_system_guid
left join sub_system ss on ss.sub_system_guid = bm.sub_system_guid
left join floor ff on ff.floor_guid = bm.planimetric_floor_guid
where bm.building_guid = '{post.build}' and bm.main_system_guid in @MainList ORDER BY ms.priority ASC, ss.priority ASC, ss.created_at DESC ", new { MainList = post.MainList });
apiResult.Code = "0000";
apiResult.Data = buildMenuTables;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
[HttpPost]
public async Task<ApiResult<BuildMenuAddSub>> GetBuildMenu(MenuIn post)
{
ApiResult<BuildMenuAddSub> apiResult = new ApiResult<BuildMenuAddSub>();
try
{
var BuildMenu = await backendRepository.GetOneAsync<BuildMenuAddSub>(
$@"select *,ss.full_name sub_system_guid_name from building_menu bm
left join sub_system ss on bm.sub_system_guid = ss.sub_system_guid
where bm.building_guid = @bg and bm.main_system_guid = @msg and bm.sub_system_guid = @ssg", new { bg = post.build, msg = post.main, ssg = post.sub });
apiResult.Code = "0000";
apiResult.Data = BuildMenu;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> DeleteBuildMenu(MenuIn post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
await backendRepository.PurgeOneByGuidWithCustomDBNameAndTable("building_menu", $"building_guid = '{post.build}' and main_system_guid = '{post.main}' and sub_system_guid = '{post.sub}'");
var authcode = await backendRepository.GetOneAsync<string>(@$"select AuthCode from auth_page where building_guid = '{post.build}' and ShowView = '{post.sub}'");
if (authcode != null)
{
await backendRepository.PurgeOneByGuidWithCustomDBNameAndTable("role_auth", $" AuthCode = '{authcode}'");
await backendRepository.PurgeOneByGuidWithCustomDBNameAndTable("auth_page", $" AuthCode = '{authcode}'");
await backendRepository.ExecuteSql(@"delete a from role_auth a join role b on a.role_guid = b.role_guid where b.layer = 0;
INSERT INTO role_auth (role_guid,AuthCode,created_by)
SELECT r.role_guid,ap.AuthCode,'0' created_by FROM auth_page ap,role r
WHERE r.layer = 0;");
#region
var sql = $@"SELECT ra.* FROM role_auth ra join role r on ra.role_guid = r.role_guid where r.layer = 0";
var role_auths = await backendRepository.GetAllAsync<RoleAuthList>(sql);
List<Dictionary<string, object>> role_auth_dicts = new List<Dictionary<string, object>>();
foreach (var role_auth in role_auths)
{
Dictionary<string, object> role_auth_dict = new Dictionary<string, object>()
{
{ "role_guid", role_auth.Role_guid},
{ "@AuthCode", role_auth.AuthCode},
};
role_auth_dicts.Add(role_auth_dict);
}
await backendRepository.ManualInsertBackgroundServiceTask("", "", "role_auth", "purge_specify_insert", role_auth_dicts);
#endregion
}
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ActionResult> BuildMenuFloorTable(MenuIn post)
{
List<BuildMenuFloorTable> buildMenuFloorTables = new List<BuildMenuFloorTable>();
ApiResult<List<BuildMenuFloorTable>> apiResult = new ApiResult<List<BuildMenuFloorTable>>();
try
{
buildMenuFloorTables = await backendRepository.GetAllAsync<BuildMenuFloorTable>($@"
select f.full_name floor_guid_name,sf.*,ms.full_name main_system_guid_name,ss.full_name sub_system_guid_name
from (select * from sub_system_floor ssf where ssf.building_guid = '{post.build}' and ssf.main_system_guid = '{post.main}' and ssf.sub_system_guid = '{post.sub}' and deleted = 0 and status = 0) sf
left join floor f on sf.floor_guid = f.floor_guid
left join main_system ms on ms.main_system_guid = sf.main_system_guid
left join sub_system ss on ss.sub_system_guid = sf.sub_system_guid
ORDER BY ms.priority, ss.priority, f.priority");
apiResult.Code = "0000";
apiResult.Data = buildMenuFloorTables;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> GetNotUsefloor(MenuIn post)
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> KeyValue = new List<KeyValue>();
try
{
var sqlString = @$"select fg.floor_guid value, fg.full_name name from
(select * from floor fg where fg.building_guid = '{post.build}' and fg.deleted = 0 and fg.status = 0 ) fg
left join (select * from sub_system_floor where building_guid = '{post.build}' and main_system_guid = '{post.main}' and sub_system_guid = '{post.sub}' and deleted = 0 and status = 0) ssf
on ssf.floor_guid = fg.floor_guid
where ssf.floor_guid is null ORDER BY fg.priority";
KeyValue = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = KeyValue;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> SaveAddsubfloor(MenuInfloor menuInfloor)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
var listdictionary = new List<Dictionary<string, object>>();
foreach (var a in menuInfloor.floorlist)
{
var dictionary = new Dictionary<string, object>()
{
{"@sub_system_floor_guid", Guid.NewGuid()},
{"@building_guid",menuInfloor.build},
{"@main_system_guid", menuInfloor.main},
{"@sub_system_guid",menuInfloor.sub},
{"@floor_guid",a},
{"@created_by", myUserInfo.Userinfo_guid}
};
listdictionary.Add(dictionary);
}
await backendRepository.AddMutiByCustomTable(listdictionary, "sub_system_floor");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(menuInfloor);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> DeleteBuildFloorMenu(string subfloorguid)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
//檢查該樓層底下是否有設備
var sql = $@"
SELECT
CONCAT(b.full_name, ' - ', ms.full_name, ' - ', ss.full_name , ' - ', f.full_name)
FROM device d
LEFT JOIN (
SELECT *
FROM sub_system_floor ssf
WHERE ssf.deleted = 0 AND ssf.sub_system_floor_guid = @Guid) ssf
ON d.deleted = 0
AND d.building_guid = ssf.building_guid
AND d.main_system_guid = ssf.main_system_guid
AND d.sub_system_guid = ssf.sub_system_guid
AND d.floor_guid = ssf.floor_guid
LEFT JOIN building b ON b.deleted = 0 AND d.building_guid = b.building_guid
LEFT JOIN main_system ms ON ms.deleted = 0 AND d.main_system_guid = ms.main_system_guid
LEFT JOIN sub_system ss ON ss.deleted = 0 AND d.sub_system_guid = ss.sub_system_guid
LEFT JOIN floor f ON f.deleted = 0 AND d.floor_guid = f.floor_guid
WHERE ssf.sub_system_floor_guid = @Guid";
var sub_system_floors = await backendRepository.GetAllAsync<string>(sql, new { Guid = subfloorguid });
if (sub_system_floors.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "設備管理中尚有設備正在使用該選單樓層,故無法刪除";
return apiResult;
}
await backendRepository.DeleteOne(subfloorguid, "sub_system_floor", "sub_system_floor_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(subfloorguid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> GetFloorInSubSystem(MenuIn post)
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> KeyValue = new List<KeyValue>();
try
{
var sqlString = @$"select floor.floor_guid Value,floor.full_name Name from sub_system_floor sf left join floor on sf.floor_guid = floor.floor_guid
where sf.deleted = 0 and sf.status = 0 and sf.building_guid = '{post.build}' and sf.main_system_guid = '{post.main}' and sf.sub_system_guid = '{post.sub}'
ORDER BY floor.priority, floor.created_at";
KeyValue = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = KeyValue;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
}
}

View File

@ -0,0 +1,751 @@
using Backend.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class DeviceImportController : MybaseController<DeviceImportController>
{
private readonly IBackendRepository backendRepository;
private readonly IDeviceImportRepository deviceImportRepository;
public DeviceImportController(IBackendRepository backendRepository, IDeviceImportRepository deviceImportRepository)
{
this.backendRepository = backendRepository;
this.deviceImportRepository = deviceImportRepository;
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// 設備匯入列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<DeviceImport>>> RawDataList()
{
ApiResult<List<DeviceImport>> apiResult = new ApiResult<List<DeviceImport>>();
List<DeviceImport> deviceImports = new List<DeviceImport>();
try
{
deviceImports = await backendRepository.GetAllAsync<DeviceImport>("device_import_temp", null, null, "device_result DESC,created_at DESC");
apiResult.Code = "0000";
apiResult.Data = deviceImports;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> ImportRawDataFile(IFormFile[] import_files)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
Dictionary<string, IWorkbook> workbooks = new Dictionary<string, IWorkbook>();
//List<IWorkbook> workbooks = new List<IWorkbook>();
#region
foreach (var import_file in import_files)
{
IWorkbook workbook;
var filename_ext = Path.GetExtension(import_file.FileName).ToLower();
if (filename_ext == ".xls")
{
workbook = new HSSFWorkbook(import_file.OpenReadStream());
workbooks.Add($"{import_file.FileName}", workbook);
}
else if (filename_ext == ".xlsx")
{
workbook = new XSSFWorkbook(import_file.OpenReadStream());
workbooks.Add($"{import_file.FileName}", workbook);
}
else
{
workbook = null;
}
if (workbook == null)
{
apiResult.Code = "9998";
apiResult.Msg = $"{import_file.FileName}該檔案失效,請重新操作。";
return apiResult;
}
}
#endregion
List<Dictionary<string, object>> deviceImports = new List<Dictionary<string, object>>();
//抓取系統類別(以供驗證判斷)
var sWhere = @$"deleted = 0 AND system_type = @system_type";
var system_category_param = new { system_type = "device_system_category_layer3" };
var system_categories_layer3 = await backendRepository.GetAllAsync<Variable>("variable", sWhere, system_category_param);
var disaster_param = new { system_type = "disaster" };
var disasters = await backendRepository.GetAllAsync<Variable>("variable", sWhere, disaster_param);
var temp_building = ""; //預設的棟別(檢查用整份excel需相同),目前只針對單一檔案情況,如後續有需再改成多檔情況。
#region
foreach (var keyValuePair in workbooks)
{
IWorkbook workbook = keyValuePair.Value;
var total_sheet = workbook.NumberOfSheets;
for (var sheet_num = 2; sheet_num < total_sheet - 1; sheet_num++)
{
var tags_name_index = -1;
var system_category_index = -1; //系統類別
var disaster_index = -1; //緊急應變程序(等同災害類別)
var sheet = workbook.GetSheetAt(sheet_num);
//表頭
IRow header = sheet.GetRow(sheet.FirstRowNum);
List<int> columns = new List<int>();
if (header != null)
{
for (int i = 0; i < header.LastCellNum; i++)
{
ICell cell = header.GetCell(i);
if (cell != null)
{
var header_str = cell.ToString().ToLower();
if (!string.IsNullOrEmpty(header_str) && header_str == "tags name")
{
tags_name_index = i;
}
if (!string.IsNullOrEmpty(header_str) && header_str == "系統類別")
{
system_category_index = i;
}
if (!string.IsNullOrEmpty(header_str) && header_str == "系統程式軟體")
{
IRow sub_header = sheet.GetRow(1);
for (int j = 0; j < sub_header.LastCellNum; j++)
{
ICell sub_cell = sub_header.GetCell(j);
var sub_header_str = sub_cell.ToString().ToLower();
if (!string.IsNullOrEmpty(sub_header_str) && sub_header_str == "緊急應變程序")
{
disaster_index = j;
}
}
}
if (tags_name_index > 0 && system_category_index > 0 && disaster_index > 0)
{
break;
}
}
}
}
//資料
if (tags_name_index < 0 || system_category_index < 0 || disaster_index < 0)
{
List<string> errMsg = new List<string>();
var result = $@"查無[{keyValuePair.Key}]在[{workbook.GetSheetName(sheet_num)}]分頁的";
if (tags_name_index < 0)
{
errMsg.Add($@"[tags name]");
}
if (system_category_index < 0)
{
errMsg.Add($@"[系統類別]");
}
if (disaster_index < 0)
{
errMsg.Add($@"[緊急應變程序]");
}
Dictionary<string, object> deviceImport = new Dictionary<string, object>()
{
{ "@device_number", null},
{ "@device_system_category_layer3", null},
{ "@device_disaster", null},
{ "@device_result", result + String.Join("、", errMsg)}
};
deviceImports.Add(deviceImport);
}
else
{
for (var i = sheet.FirstRowNum + 2; i < sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);
if (row != null)
{
List<string> errMsg = new List<string>();
Dictionary<string, object> deviceImport = new Dictionary<string, object>();
ICell tags_name_cell = row.GetCell(tags_name_index);
if (tags_name_cell != null)
{
var tempData = tags_name_cell.ToString().Trim();
var system_category = string.Empty;
var disaster = string.Empty;
if (!string.IsNullOrEmpty(tempData))
{
var arr_tempData = tempData.Split('_');
#region tags name驗證條件
if (string.IsNullOrEmpty(temp_building)) //抓第一筆當作該excel 比對棟別的依據
{
temp_building = arr_tempData[0];
}
else
{
if (temp_building != arr_tempData[0])
{
errMsg.Add("資料棟別錯誤");
}
}
if (arr_tempData.Length != 5)
{
errMsg.Add("資料格式錯誤");
}
if (arr_tempData[arr_tempData.Length - 1].Contains(''))
{
errMsg.Add("設備流水號格式錯誤");
}
if (arr_tempData[arr_tempData.Length - 1].Split('~').Length > 2)
{
errMsg.Add("設備流水號格式錯誤");
}
#endregion
#region
ICell system_category_cell = row.GetCell(system_category_index);
if (system_category_cell == null)
{
errMsg.Add(@"該設備的[系統類別]未填值");
}
else
{
system_category = system_category_cell.ToString().Trim();
if (!string.IsNullOrEmpty(system_category))
{
var exist = system_categories_layer3.Exists(x => x.system_value == system_category);
if (!exist)
{
errMsg.Add(@"該設備的[系統類別]不存在");
}
}
else
{
errMsg.Add(@"該設備的[系統類別]未填值");
}
}
#endregion
#region
ICell disaster_cell = row.GetCell(disaster_index);
if (disaster_cell == null)
{
errMsg.Add(@"該設備的[緊急應變程序]未填值");
}
else
{
disaster = disaster_cell.ToString().Trim();
if (!string.IsNullOrEmpty(disaster))
{
if (disaster != "0")
{
var exist = disasters.Exists(x => x.system_value == disaster);
if (!exist)
{
errMsg.Add(@"該設備的[緊急應變程序]不存在");
}
}
}
else
{
errMsg.Add(@"該設備的[緊急應變程序]未填值");
}
}
#endregion
if (errMsg.Count > 0)
{
deviceImport.Add("@device_number", tempData);
deviceImport.Add("@device_system_category_layer3", system_category);
deviceImport.Add("@device_disaster", disaster);
deviceImport.Add("@device_result", String.Join(", ", errMsg));
}
else
{
deviceImport.Add("@device_number", tempData);
deviceImport.Add("@device_system_category_layer3", system_category);
deviceImport.Add("@device_disaster", disaster);
deviceImport.Add("@device_result", null);
}
deviceImports.Add(deviceImport);
}
}
}
}
}
}
}
deviceImports = deviceImports.Distinct().ToList();
//先刪除整份資料表
var sql = @"IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[device_import_temp]') AND type in (N'U'))
BEGIN
DROP TABLE [dbo].[device_import_temp];
END
CREATE TABLE [dbo].[device_import_temp](
[id] [int] IDENTITY(1,1) NOT NULL,
[device_number] [nvarchar](255) NULL,
[device_system_category_layer3] [varchar](50) NULL,
[device_disaster] [varchar](50) NULL,
[device_result] [nvarchar](255) NULL,
[created_at] [datetime] NULL,
CONSTRAINT [PK_device_import_temp] PRIMARY KEY CLUSTERED
(
[id] ASC
))
ALTER TABLE [dbo].[device_import_temp] ADD CONSTRAINT [DF_device_import_temp_device_disaster] DEFAULT ((0)) FOR [device_disaster]
ALTER TABLE [dbo].[device_import_temp] ADD CONSTRAINT [DF_device_import_temp_created_at] DEFAULT (getdate()) FOR [created_at]
";
await backendRepository.ExecuteSql(sql);
//如有發現錯誤直接insert 至 device_import_temp不做後續處理
await backendRepository.AddMutiByCustomTable(deviceImports, "device_import_temp");
//var err = deviceImports.Where(x => x.ContainsKey("@device_result")).Select(x => x.Values).ToList();
var err = deviceImports.SelectMany(x => x).Where(x => x.Key == "@device_result" && x.Value != null).ToList();
if (err.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "資料內容有誤,請重新匯入。";
return apiResult;
}
else
{
//拆分每一份資料
List<Dictionary<string, object>> deviceImportChecks = new List<Dictionary<string, object>>(); //檢查OK的列表
foreach (var deviceImport in deviceImports)
{
object device_number = null;
object device_system_category_layer3 = null;
object device_disaster = null;
deviceImport.TryGetValue("@device_number", out device_number);
deviceImport.TryGetValue("@device_system_category_layer3", out device_system_category_layer3);
deviceImport.TryGetValue("@device_disaster", out device_disaster);
var arr_device_number = device_number.ToString().Split('_');
//抓出是否為組數的設備
var arr_device_number_final_col = arr_device_number[arr_device_number.Length - 1].Contains('~') ? arr_device_number[arr_device_number.Length - 1].Split('~') : null;
if (arr_device_number_final_col != null && arr_device_number_final_col.Length > 0)
{
var start_num = Convert.ToInt32(arr_device_number_final_col[0].Trim());
var end_num = Convert.ToInt32(arr_device_number_final_col[1].Trim());
for (var i = start_num; i <= end_num; i++)
{
Dictionary<string, object> deviceImportCheck = new Dictionary<string, object>();
var pre_device_number = String.Join('_', arr_device_number, 0, 4);
deviceImportCheck.Add("@device_building_tag", arr_device_number[0]); //設備區域
deviceImportCheck.Add("@device_system_tag", arr_device_number[1]); //設備系統別
deviceImportCheck.Add("@device_floor_tag", arr_device_number[2]); //設備樓層
deviceImportCheck.Add("@device_name_tag", arr_device_number[3]); //設備名稱
var pad = string.Empty;
if(i < 10)
{
pad = i.ToString().PadLeft(2, '0');
}
else
{
pad = i.ToString();
}
deviceImportCheck.Add("@device_serial_tag", pad); //設備流水號
deviceImportCheck.Add("@device_number", pre_device_number + "_" + pad); //設備完整編號
deviceImportCheck.Add("@device_system_category_layer3", device_system_category_layer3.ToString()); //系統類別(第3層)
deviceImportCheck.Add("@device_disaster", device_disaster.ToString()); //緊急應變程序
deviceImportCheck.Add("@is_correct", 0); //驗證是否正確
deviceImportChecks.Add(deviceImportCheck);
}
}
else
{
Dictionary<string, object> deviceImportCheck = new Dictionary<string, object>();
var pre_device_number = String.Join('_', arr_device_number, 0, 3);
deviceImportCheck.Add("@device_building_tag", arr_device_number[0]); //設備區域
deviceImportCheck.Add("@device_system_tag", arr_device_number[1]); //設備系統別
deviceImportCheck.Add("@device_floor_tag", arr_device_number[2]); //設備樓層
deviceImportCheck.Add("@device_name_tag", arr_device_number[3]); //設備名稱
deviceImportCheck.Add("@device_serial_tag", arr_device_number[4]); //設備流水號
deviceImportCheck.Add("@device_number", device_number); //設備完整編號
deviceImportCheck.Add("@device_system_category_layer3", device_system_category_layer3.ToString()); //系統類別(第3層)
deviceImportCheck.Add("@device_disaster", device_disaster.ToString()); //緊急應變程序
deviceImportCheck.Add("@is_correct", 0); //驗證是否正確
deviceImportChecks.Add(deviceImportCheck);
}
}
//針對棟別刪除檢查OK的設備查詢表
var sDeleteWhere = $@"device_building_tag = '{temp_building}'";
await backendRepository.PurgeOneByGuidWithCustomDBNameAndTable("device_import_ckeck_temp", sDeleteWhere);
//var sql_check = @"IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[device_import_ckeck_temp]') AND type in (N'U'))
// BEGIN
// DROP TABLE [dbo].[device_import_ckeck_temp]
// END
// CREATE TABLE [dbo].[device_import_ckeck_temp](
// [id] [int] IDENTITY(1,1) NOT NULL,
// [device_building_tag] [nvarchar](50) NULL,
// [device_system_tag] [nvarchar](50) NULL,
// [device_floor_tag] [nvarchar](50) NULL,
// [device_kind] [nvarchar](50) NULL,
// [device_name_tag] [nvarchar](50) NULL,
// [device_serial_tag] [nvarchar](50) NULL,
// [device_number] [nvarchar](255) NULL,
// [device_system_category_layer3] [varchar](50) NULL,
// [device_disaster] [varchar](50) NULL,
// [created_at] [datetime] NULL,
// CONSTRAINT [PK_device_import_ckeck_temp] PRIMARY KEY CLUSTERED
// (
// [id] ASC
// ))
// ALTER TABLE [dbo].[device_import_ckeck_temp] ADD CONSTRAINT [DF_device_import_ckeck_temp_device_disaster] DEFAULT ((0)) FOR [device_disaster]
// ALTER TABLE [dbo].[device_import_ckeck_temp] ADD CONSTRAINT [DF_device_import_ckeck_temp_created_at] DEFAULT (getdate()) FOR [created_at]
// ";
//await backendRepository.ExecuteSql(sql_check);
//檢查正確才寫入至check_temp資料表
await backendRepository.AddMutiByCustomTable(deviceImportChecks, "device_import_ckeck_temp");
}
apiResult.Code = "0000";
apiResult.Msg = "匯入成功";
#endregion
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 取得設備檢核上方過濾選單
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<DeviceCheckFilter>>> GetRawDataCheckFilter()
{
ApiResult<List<DeviceCheckFilter>> apiResult = new ApiResult<List<DeviceCheckFilter>>();
try
{
string sql = $@"
SELECT
ct.device_building_tag,
ct.device_system_tag,
ct.device_system_category_layer3
FROM device_import_ckeck_temp ct
GROUP BY ct.device_building_tag, ct.device_system_tag, ct.device_system_category_layer3
";
var deviceCheckFilterRawDatas = await backendRepository.GetAllAsync<DeviceCheckFilterRawData>(sql);
List<DeviceCheckFilter> deviceCheckFilters = new List<DeviceCheckFilter>();
var deviceCheckFilterRawData_Group_Building_tag = deviceCheckFilterRawDatas.GroupBy(x => x.Device_building_tag).ToList();
foreach (var deviceCheckFilterRawData_Building_tag in deviceCheckFilterRawData_Group_Building_tag)
{
DeviceCheckFilter deviceCheckFilter = new DeviceCheckFilter();
deviceCheckFilter.Building_tag = deviceCheckFilterRawData_Building_tag.Key;
var sql_amount = @"SELECT COUNT(*) FROM device_import_ckeck_temp WHERE device_building_tag = @Device_building_tag";
deviceCheckFilter.Building_amount = await backendRepository.GetOneAsync<int>(sql_amount, new { Device_building_tag = deviceCheckFilterRawData_Building_tag.Key });
deviceCheckFilter.System_tags = new List<DeviceCheckSystemTag>();
var deviceCheckFilterRawData_Group_System_tag = deviceCheckFilterRawData_Building_tag.GroupBy(x => x.Device_system_tag).ToList();
foreach (var deviceCheckFilterRawData_System_tag in deviceCheckFilterRawData_Group_System_tag)
{
DeviceCheckSystemTag deviceCheckSystemTag = new DeviceCheckSystemTag();
deviceCheckSystemTag.System_tag = deviceCheckFilterRawData_System_tag.Key;
deviceCheckSystemTag.System_categories = new List<string>();
var deviceCheckFilterRawData_Group_System_category = deviceCheckFilterRawData_System_tag.GroupBy(x => x.Device_system_category_layer3).ToList();
foreach (var deviceCheckFilterRawData_System_category in deviceCheckFilterRawData_Group_System_category)
{
deviceCheckSystemTag.System_categories.Add(deviceCheckFilterRawData_System_category.Key);
}
deviceCheckFilter.System_tags.Add(deviceCheckSystemTag);
}
deviceCheckFilters.Add(deviceCheckFilter);
}
apiResult.Code = "0000";
apiResult.Data = deviceCheckFilters;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 資料檢核表格
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<DeviceCheck>> DeviceCheckTableList(PostDeviceCheckFilter post)
{
ApiResult<DeviceCheck> apiResult = new ApiResult<DeviceCheck>();
try
{
string sWhere = "";
string sSubTableWhere = " WHERE {0}.device_building_tag = @Device_building_tag";
if (post.Abnormal == "all")
{ //異常分類 為全選的時候,才可以指定選擇系統別、設備分類
if (post.System_tag != "all")
{
sSubTableWhere += " AND {0}.device_system_tag = @Device_system_tag";
}
if (post.System_category != "all")
{
sSubTableWhere += " AND {0}.device_system_category_layer3 = @Device_system_category_layer3";
}
}
else
{
sWhere += @"WHERE ct.device_number IS NULL AND d.device_number IS NOT NULL
-- OR ct.device_system_category_layer3 != d.device_system_category_layer3
-- OR ct.disaster_system_value != d.device_disaster";
}
string sql_temp = $@"
SELECT
ct.device_number AS check_temp_device_number,
ct.device_system_category_layer3 AS check_temp_device_system_category_layer3,
ct.system_category_system_key AS check_temp_device_system_category_layer3_key,
ct.disaster_system_value AS check_temp_disaster,
ct.disaster_system_key AS check_temp_disaster_key,
d.device_number,
d.device_system_category_layer3 AS device_system_category_layer3,
d.system_key AS device_system_category_layer3_key,
d.device_disaster,
d.device_disaster_type_text,
d.device_coordinate,
CASE
WHEN ct.device_number = d.device_number
THEN 0
ELSE 1
END AS compare_device_number,
CASE
WHEN ct.device_system_category_layer3 = d.device_system_category_layer3
THEN 0
ELSE 1
END AS compare_system_category_layer3,
CASE
WHEN ct.disaster_system_value = d.device_disaster
THEN 0
ELSE 1
END AS compare_device_disaster
FROM (
SELECT
ct.* ,
v.system_type AS system_category_system_type,
v.system_key AS system_category_system_key,
v.system_value AS system_category_system_value,
v2.system_type AS disaster_system_type,
v2.system_key AS disaster_system_key,
v2.system_value AS disaster_system_value
FROM device_import_ckeck_temp ct
LEFT JOIN variable v ON v.system_type = 'device_system_category_layer3' AND ct.device_system_category_layer3 = v.system_value
LEFT JOIN variable v2 ON v2.system_type = 'disaster' AND v2.system_value = ct.device_disaster
{{0}}
) ct
FULL JOIN (
SELECT
d.* ,
v.system_type,
v.system_key,
v.system_value,
(SELECT
STRING_AGG( ISNULL(system_value, ' '), ',')
FROM device_disaster dd
JOIN variable v ON v.deleted = 0 AND v.system_type = 'disaster' AND v.system_value = dd.device_system_value
WHERE dd.device_guid = d.device_guid
) AS device_disaster,
(SELECT
STRING_AGG( ISNULL(system_key, ' '), ',')
FROM device_disaster dd
JOIN variable v ON v.deleted = 0 AND v.system_type = 'disaster' AND v.system_value = dd.device_system_value
WHERE dd.device_guid = d.device_guid
) AS device_disaster_type_text
FROM device d
LEFT JOIN variable v ON v.system_type = 'device_system_category_layer3' AND d.device_system_category_layer3 = v.system_value
{{1}}
AND d.deleted = 0
)d ON ct.device_number = d.device_number
{{2}}
ORDER BY d.device_number DESC
";
var sql = string.Format(sql_temp, string.Format(sSubTableWhere, "ct"), string.Format(sSubTableWhere, "d"), sWhere);
var param = new { Device_building_tag = post.Building_tag, Device_system_tag = post.System_tag, Device_system_category_layer3 = post.System_category };
var deviceCheckTableList = await backendRepository.GetAllAsync<DeviceCheckTable>(sql, param);
sSubTableWhere = " WHERE {0}.device_building_tag = @Device_building_tag";
sWhere = @"WHERE ct.device_number IS NULL AND d.device_number IS NOT NULL
-- OR ct.device_system_category_layer3 != d.device_system_category_layer3
-- OR ct.disaster_system_value != d.device_disaster";
var sql_abnormal_amount = string.Format(sql_temp, string.Format(sSubTableWhere, "ct"), string.Format(sSubTableWhere, "d") + " AND d.deleted = 0", sWhere);
var abnormal = await backendRepository.GetAllAsync<DeviceCheckTable>(sql_abnormal_amount, param);
var abnormal_amount = abnormal.Count();
DeviceCheck deviceCheck = new DeviceCheck();
deviceCheck.DeviceCheckAmount = abnormal_amount;
deviceCheck.DeviceCheckTableList = deviceCheckTableList;
apiResult.Code = "0000";
apiResult.Data = deviceCheck;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 資料檢核表格
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> DeviceCheckReplace(PostDeviceCheckFilter post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
//將該棟別的資料更換為正確
string sql_update_correct = @"UPDATE device_import_ckeck_temp SET is_correct = 1 WHERE device_building_tag = @Device_building_tag";
var param = new { Device_building_tag = post.Building_tag };
await backendRepository.ExecuteSql(sql_update_correct, param);
//找出當前在device裡面有的以供後續取代用
string sql = @"
SELECT
ct.*,
d.device_guid
FROM (
SELECT
*
FROM device_import_ckeck_temp ct
WHERE ct.device_number IN (
SELECT d.device_number
FROM device d
WHERE d.deleted = 0
AND d.device_building_tag = @Device_building_tag
)
) ct
LEFT JOIN device d ON d.deleted = 0 AND ct.device_number = d.device_number";
var check_temp_replaces = await backendRepository.GetAllAsync<Device_import_ckeck_temp_replace>(sql, param);
foreach (var check_temp_replace in check_temp_replaces)
{
Dictionary<string, object> device_replace = new Dictionary<string, object>()
{
{"@device_system_category_layer3", check_temp_replace.Device_system_category_layer3},
};
List<Dictionary<string, object>> device_disaster_dicts = new List<Dictionary<string, object>>()
{
{ new Dictionary<string, object>() { { "@device_guid", check_temp_replace.Device_guid }, { "@device_system_value", check_temp_replace.Device_disaster } } }
};
await deviceImportRepository.ReplaceOneDeviceInfo(check_temp_replace.Device_guid, device_replace, device_disaster_dicts);
}
apiResult.Code = "0000";
apiResult.Msg = "取代成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,232 @@
using Backend.Models;
using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class EmergencyContactController : MybaseController<EmergencyContactController>
{
private readonly IBackendRepository backendRepository;
public EmergencyContactController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
public async Task<ActionResult> EmergencyContactTable (List<int> selectgroupidlist)
{
List<EmergencyContactTable> Emergency_member_tables = new List<EmergencyContactTable>();
ApiResult<List<EmergencyContactTable>> apiResult = new ApiResult<List<EmergencyContactTable>>();
try
{
Emergency_member_tables = await backendRepository.GetAllAsync<EmergencyContactTable>($@"
select v.system_key groupingName,va.system_key departmentName,* from emergency_member em left join variable v on em.grouping = v.id
left join (select * from variable vs where vs.system_type = 'department' and vs.deleted = 0) va on va.system_value = em.department
where em.grouping in @groupinglist and em.deleted = 0",new { groupinglist = selectgroupidlist });
apiResult.Code = "0000";
apiResult.Data = Emergency_member_tables;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
public FileResult ExportPDF(string post)
{
var grouping = JsonConvert.DeserializeObject<export>(post);
var stream = new MemoryStream();
try
{
var Emergency_member_tables = backendRepository.GetAllAsync<EmergencyContactTable>($@"
select v.system_key groupingName,va.system_key departmentName,* from emergency_member em left join variable v on em.grouping = v.id
left join (select * from variable vs where vs.system_type = 'department' and vs.deleted = 0) va on va.system_value = em.department
where em.grouping in @groupinglist and em.deleted = 0", new { groupinglist = grouping.groupidlist });
using (var doc = new Document())
{
using (var writer = PdfWriter.GetInstance(doc, stream))
{
writer.CloseStream = false;
BaseFont BaseF = BaseFont.CreateFont("C:\\Windows\\Fonts\\kaiu.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font fontCh = new Font(BaseF, 14);
doc.Open();
PdfPTable table = new PdfPTable(new float[] { 1, 1, 1, 1, 1 ,1 });
table.TotalWidth = 480f;
table.LockedWidth = true;
PdfPCell header = new PdfPCell(new Phrase(grouping.disaster+"-聯絡清單", fontCh));
header.Colspan = 6;
table.AddCell(header);
table.AddCell(new Phrase("組別", fontCh));
table.AddCell(new Phrase("姓名", fontCh));
table.AddCell(new Phrase("部門", fontCh));
table.AddCell(new Phrase("電話", fontCh));
table.AddCell(new Phrase("LINE ID", fontCh));
table.AddCell(new Phrase("電子信箱", fontCh));
foreach(var group in Emergency_member_tables.Result)
{
table.AddCell(new Phrase(group.groupingName, fontCh));
table.AddCell(new Phrase(group.full_name, fontCh));
table.AddCell(new Phrase(group.departmentName, fontCh));
table.AddCell(new Phrase(group.phone, fontCh));
table.AddCell(new Phrase(group.lineid, fontCh));
table.AddCell(new Phrase(group.email, fontCh));
}
doc.Add(table);
doc.Close();
}
}
var bytes = stream.ToArray();
stream.Position = 0;
}
catch (Exception exception)
{
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return File(stream, "application/pdf", grouping.disaster+"-聯絡清單.pdf");
}
public FileResult ExportExcel(string post)
{
var grouping = JsonConvert.DeserializeObject<export>(post);
var workbook = new XSSFWorkbook();
var ms = new NpoiMemoryStream
{
AllowClose = false
};
#region excel設定
IFont font12 = workbook.CreateFont();
font12.FontName = "新細明體";
font12.FontHeightInPoints = 12;
ICellStyle style12 = workbook.CreateCellStyle();
style12.SetFont(font12);
style12.Alignment = HorizontalAlignment.Center;
style12.VerticalAlignment = VerticalAlignment.Center;
IFont font12Times = workbook.CreateFont();
font12Times.FontName = "Times New Roman";
font12Times.FontHeightInPoints = 12;
IFont font18 = workbook.CreateFont();
font18.FontName = "新細明體";
font18.FontHeightInPoints = 18;
font18.IsBold = true;
ICellStyle styleTitle18 = workbook.CreateCellStyle();
styleTitle18.SetFont(font18);
styleTitle18.Alignment = HorizontalAlignment.Center;
styleTitle18.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLeft12 = workbook.CreateCellStyle();
styleLeft12.SetFont(font12);
styleLeft12.Alignment = HorizontalAlignment.Left;
styleLeft12.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLine12 = workbook.CreateCellStyle();
styleLine12.SetFont(font12);
styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
styleLine12.VerticalAlignment = VerticalAlignment.Center;
styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
ICellStyle stylein12 = workbook.CreateCellStyle();
stylein12.SetFont(font12Times);
stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
stylein12.VerticalAlignment = VerticalAlignment.Center;
stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.WrapText = true;
#endregion
try
{
var Emergency_member_tables = backendRepository.GetAllAsync<EmergencyContactTable>($@"
select v.system_key groupingName,va.system_key departmentName,* from emergency_member em left join variable v on em.grouping = v.id
left join (select * from variable vs where vs.system_type = 'department' and vs.deleted = 0) va on va.system_value = em.department
where em.grouping in @groupinglist and em.deleted = 0", new { groupinglist = grouping.groupidlist }).Result;
var sheet = workbook.CreateSheet(grouping.disaster+"-聯絡清單");
int RowPosition = 0;
IRow row = sheet.CreateRow(RowPosition);
sheet.SetColumnWidth(0, 4 * 160 * 6);
sheet.SetColumnWidth(1, 4 * 160 * 6);
sheet.SetColumnWidth(2, 4 * 160 * 6);
sheet.SetColumnWidth(3, 4 * 160 * 6);
sheet.SetColumnWidth(4, 4 * 160 * 6);
sheet.SetColumnWidth(5, 4 * 160 * 6);
ICell cell = row.CreateCell(0);
cell.SetCellValue("組別");
cell.CellStyle = styleLine12;
cell = row.CreateCell(1);
cell.SetCellValue("姓名");
cell.CellStyle = styleLine12;
cell = row.CreateCell(2);
cell.SetCellValue("部門");
cell.CellStyle = styleLine12;
cell = row.CreateCell(3);
cell.SetCellValue("電話");
cell.CellStyle = styleLine12;
cell = row.CreateCell(4);
cell.SetCellValue("LINE ID");
cell.CellStyle = styleLine12;
cell = row.CreateCell(5);
cell.SetCellValue("電子信箱");
cell.CellStyle = styleLine12;
foreach (var group in Emergency_member_tables)
{
RowPosition += 1;
row = sheet.CreateRow(RowPosition);
cell = row.CreateCell(0);
cell.SetCellValue(group.groupingName);
cell.CellStyle = style12;
cell = row.CreateCell(1);
cell.SetCellValue(group.full_name);
cell.CellStyle = style12;
cell = row.CreateCell(2);
cell.SetCellValue(group.departmentName);
cell.CellStyle = style12;
cell = row.CreateCell(3);
cell.SetCellValue(group.phone);
cell.CellStyle = style12;
cell = row.CreateCell(4);
cell.SetCellValue(group.lineid);
cell.CellStyle = style12;
cell = row.CreateCell(5);
cell.SetCellValue(group.email);
cell.CellStyle = style12;
}
workbook.Write(ms);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
}
catch(Exception exception)
{
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return File(ms, "application/vnd.ms-excel", grouping.disaster + "-聯絡清單.xlsx");
}
}
}

View File

@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Mvc;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class EmergencyDeviceMenuController : MybaseController<EmergencyDeviceMenuController>
{
private readonly IBackendRepository backendRepository;
public EmergencyDeviceMenuController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// 取得系統大類清單
/// </summary>
/// <returns></returns>
//[HttpPost]
//public async Task<ApiResult<List<SystemMain>>> SystemMainList()
//{
// ApiResult<List<SystemMain>> apiResult = new ApiResult<List<SystemMain>>();
// try
// {
// var sWhere = "deleted = 0";
// var systemMainList = await backendRepository.GetAllAsync<SystemMain>("main_system", sWhere, null, "priority ASC, created_at DESC");
// apiResult.Code = "0000";
// apiResult.Data = systemMainList;
// }
// catch (Exception exception)
// {
// apiResult.Code = "9999";
// Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
// }
// return apiResult;
//}
}
}

View File

@ -0,0 +1,278 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class EmergencyGroupingController : MybaseController<EmergencyGroupingController>
{
private readonly IBackendRepository backendRepository;
public EmergencyGroupingController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> Getdepartlist()
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> Variable = new List<KeyValue>();
try
{
var sqlString = @$"select system_value as Value, system_key as Name from variable a where a.system_type = 'department' and a.deleted = 0";
Variable = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = Variable;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> SaveGrouping(SaveGrouping post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
if(post.id == 0)
{
var value = await backendRepository.GetOneAsync<int>("select td.system_value from variable td where td.system_type = 'grouping' order by td.system_value desc");
var dictionary = new Dictionary<string, object>()
{
{"@system_type", "grouping"},
{"@system_key",post.name},
{"@system_value", value + 1},
{"@system_remark","急救編組"},
{"@system_priority",post.priority},
{"@system_parent_id", post.disaster}
};
await backendRepository.AddOneByCustomTable(dictionary, "variable");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
var dictionary = new Dictionary<string, object>()
{
{"@system_key",post.name},
{"@system_priority",post.priority}
};
await backendRepository.UpdateOneByCustomTable(dictionary, "variable", $" id = {post.id}");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
}
catch(Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ActionResult> Emergency_member_table(int grouping)
{
List<Emergency_member_table> Emergency_member_tables = new List<Emergency_member_table>();
ApiResult<List<Emergency_member_table>> apiResult = new ApiResult<List<Emergency_member_table>>();
try
{
Emergency_member_tables = await backendRepository.GetAllAsync<Emergency_member_table>($@"
select v.system_key grouping_name,va.system_key department_name,* from emergency_member em left join variable v on em.grouping = v.id
left join (select * from variable vs where vs.system_type = 'department' and vs.deleted = 0) va on va.system_value = em.department
where em.grouping = {grouping} and em.deleted = 0");
apiResult.Code = "0000";
apiResult.Data = Emergency_member_tables;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
[HttpPost]
public async Task<ApiResult<List<KeyValueID>>> GetGroupingList (int system_parent_id)
{
ApiResult<List<KeyValueID>> apiResult = new ApiResult<List<KeyValueID>>();
List<KeyValueID> keyvalue = new List<KeyValueID>();
try
{
keyvalue = await backendRepository.GetAllAsync<KeyValueID>($"select id, system_key as name,system_value as value from variable where deleted = 0 and system_parent_id = {system_parent_id} and system_type = 'grouping' order by system_priority");
apiResult.Data = keyvalue;
apiResult.Code = "0000";
}
catch(Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + system_parent_id);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<SaveGrouping>> GetOneGrouping(int selectgroupid)
{
ApiResult<SaveGrouping> apiResult = new ApiResult<SaveGrouping>();
try
{
var group = await backendRepository.GetOneAsync<SaveGrouping>($"select v.system_priority as priority,v.system_key as name,id from variable v where id = {selectgroupid} and deleted = 0");
apiResult.Data = group;
apiResult.Code = "0000";
}
catch(Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + selectgroupid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>>DeleteOne(int selectgroupid)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
await backendRepository.DeleteOne(selectgroupid.ToString(), "variable", "id");
apiResult.Msg = "刪除成功";
apiResult.Code = "0000";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + selectgroupid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>>SaveMember(Emergency_member post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
if (post.emergency_member_guid == null)
{
var dictionary = new Dictionary<string, object>()
{
{"@emergency_member_guid", Guid.NewGuid()},
{"@grouping",post.grouping},
{"@full_name", post.full_name},
{"@department",post.department},
{"@phone",post.phone},
{"@lineid", post.lineid},
{"@email", post.email},
{"@created_by",myUserInfo.Userinfo_guid }
};
await backendRepository.AddOneByCustomTable(dictionary, "emergency_member");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
var dictionary = new Dictionary<string, object>()
{
{"@grouping",post.grouping},
{"@full_name", post.full_name},
{"@department",post.department},
{"@phone",post.phone},
{"@lineid", post.lineid},
{"@email", post.email},
{"@updated_by",myUserInfo.Userinfo_guid },
{"@updated_at",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }
};
await backendRepository.UpdateOneByCustomTable(dictionary, "emergency_member", $"emergency_member_guid = '{post.emergency_member_guid}'");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<Emergency_member>> GetOneMember(string guid)
{
ApiResult<Emergency_member> apiResult = new ApiResult<Emergency_member>();
try
{
var member = await backendRepository.GetOneAsync<Emergency_member>("emergency_member", $"emergency_member_guid = '{guid}'");
apiResult.Data = member;
apiResult.Code = "0000";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> DeletedOneMember(string guid)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
await backendRepository.DeleteOne(guid, "emergency_member", "emergency_member_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
}
}

View File

@ -0,0 +1,94 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class EmergencyRecordController : MybaseController<EmergencyRecordController>
{
private readonly IBackendRepository backendRepository;
public EmergencyRecordController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
public async Task<ActionResult> EmergencyRecordTable(EmergencyRecordEventPost post)
{
List<EmergencyRecordEventTable> EmergencyRecordEvent = new List<EmergencyRecordEventTable>();
ApiResult<List<EmergencyRecordEventTable>> apiResult = new ApiResult<List<EmergencyRecordEventTable>>();
try
{
var sqlplus = "";
if(post.selectaType != 2 )
{
sqlplus = $"and ee.type = '{post.selectaType}'";
}
if (post.dateranger != null)
{
var date = post.dateranger.Replace(" ", "").Split("-");
sqlplus += $"and ee.created_at between '{date[0].Replace(" / ", " - ")} 00:00:00' and '{date[1].Replace(" / ", " - ")} 23:59:59'";
}
EmergencyRecordEvent = await backendRepository.GetAllAsync<EmergencyRecordEventTable>($@"
select d.device_number device_name,v.system_key disaster_name,ee.*,b.full_name building_name from emergency_event ee
left join (select * from variable v where v.system_type = 'disaster') v on v.system_value = ee.disaster
left join device d on d.device_guid = ee.device_guid
left join building b on b.building_guid = ee.building_guid
where ee.deleted = 0 and ee.building_guid = '{post.selectaBuild}' and ee.disaster = '{post.selectaDisaster}' {sqlplus}
");
apiResult.Code = "0000";
apiResult.Data = EmergencyRecordEvent;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
[HttpPost]
public async Task<ActionResult> EmergencyItemTable(string event_guid)
{
List<EmergencyRecordItem> EmergencyRecordEvent = new List<EmergencyRecordItem>();
ApiResult<List<EmergencyRecordItem>> apiResult = new ApiResult<List<EmergencyRecordItem>>();
try
{
EmergencyRecordEvent = await backendRepository.GetAllAsync<EmergencyRecordItem>($@"
select * from emergency_item where event_guid = '{event_guid}' order by created_at desc
");
apiResult.Code = "0000";
apiResult.Data = EmergencyRecordEvent;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
}
}

View File

@ -0,0 +1,558 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
namespace Backend.Controllers
{
public class EmergencySettingController : MybaseController<EmergencySettingController>
{
private readonly IBackendRepository backendRepository;
public EmergencySettingController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> DisasterList()
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> Variable = new List<KeyValue>();
try
{
var sqlString = @$"select system_value as Value, system_key as Name from variable a where a.system_type = 'disaster' and a.deleted = 0";
Variable = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = Variable;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<List<KeyValueID>>> GetSettingList(int system_parent_id)
{
ApiResult<List<KeyValueID>> apiResult = new ApiResult<List<KeyValueID>>();
List<KeyValueID> keyvalue = new List<KeyValueID>();
try
{
keyvalue = await backendRepository.GetAllAsync<KeyValueID>($"select id, system_key as name,system_value as value from variable where deleted = 0 and system_parent_id = {system_parent_id} and system_type = 'DisasterSetting' order by system_priority");
apiResult.Data = keyvalue;
apiResult.Code = "0000";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + system_parent_id);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> SaveSettingModal(SaveGrouping post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
if (post.id == 0)
{
var value = await backendRepository.GetOneAsync<int>("select td.system_value from variable td where td.system_type = 'DisasterSetting' order by cast(td.system_value as int) desc");
var dictionary = new Dictionary<string, object>()
{
{"@system_type", "DisasterSetting"},
{"@system_key",post.name},
{"@system_value", value + 1},
{"@system_remark","急救大步驟設定"},
{"@system_priority",post.priority},
{"@system_parent_id", post.disaster}
};
await backendRepository.AddOneByCustomTable(dictionary, "variable");
var Nid = await backendRepository.GetOneAsync<int>($"select id from variable where system_type = 'DisasterSetting' and system_key = N'{post.name}' and system_value = '{value + 1}'");
var dictionary2 = new Dictionary<string, object>()
{
{"@system_type", "Verify"},
{"@system_key","驗證開關"},
{"@system_remark","急救大步驟設定驗證開關"},
{"@system_priority",0},
{"@system_parent_id", Nid}
};
if (post.verify == 0)
{
dictionary2.Add("@system_value", 0);
}
else
{
dictionary2.Add("@system_value", 1);
}
await backendRepository.AddOneByCustomTable(dictionary2, "variable");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
var dictionary = new Dictionary<string, object>()
{
{"@system_key",post.name},
{"@system_priority",post.priority}
};
await backendRepository.UpdateOneByCustomTable(dictionary, "variable", $" id = {post.id}");
if (post.verify == 0)
{
var dictionary2 = new Dictionary<string, object>()
{
{"@system_value",0}
};
await backendRepository.UpdateOneByCustomTable(dictionary2, "variable", $" system_type = 'Verify' and system_parent_id = '{post.id}'");
}
else
{
var haveVerify = await backendRepository.GetOneAsync<string>("variable", $"system_type = 'Verify' and system_parent_id = '{post.id}'");
if (haveVerify == null)
{
var dictionary2 = new Dictionary<string, object>()
{
{"@system_type", "Verify"},
{"@system_key","驗證開關"},
{"@system_remark","急救大步驟設定驗證開關"},
{"@system_priority",0},
{"@system_parent_id", post.id},
{"@system_value", 1}
};
await backendRepository.AddOneByCustomTable(dictionary2, "variable");
}
else
{
var dictionary2 = new Dictionary<string, object>()
{
{"@system_value",1}
};
await backendRepository.UpdateOneByCustomTable(dictionary2, "variable", $" system_type = 'Verify' and system_parent_id = '{post.id}'");
}
}
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> SaveSubSetting(EmergencySetting post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
if (post.emergency_guid == null)
{
var dictionary = new Dictionary<string, object>()
{
{"@emergency_guid", Guid.NewGuid()},
{"@priority",post.priority},
{"@big_setting", post.big_setting},
{"@full_name",post.full_name},
{"@set_doing",post.set_doing},
{"@url_text", post.url_text},
{"@url_link", post.url_link},
{"@not_answer",post.not_answer},
{"@created_by",myUserInfo.Userinfo_guid }
};
await backendRepository.AddOneByCustomTable(dictionary, "emergency_setting");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
var dictionary = new Dictionary<string, object>()
{
{"@priority",post.priority},
{"@big_setting", post.big_setting},
{"@full_name",post.full_name},
{"@set_doing",post.set_doing},
{"@url_text", post.url_text},
{"@url_link", post.url_link},
{"@not_answer",post.not_answer},
{"@updated_by",myUserInfo.Userinfo_guid },
{"@updated_at",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }
};
await backendRepository.UpdateOneByCustomTable(dictionary, "emergency_setting", $"emergency_guid = '{post.emergency_guid}'");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ActionResult> Emergency_Setting_table(int selectsetting)
{
List<EmergencySettingTable> Emergency_Setting_tables = new List<EmergencySettingTable>();
ApiResult<List<EmergencySettingTable>> apiResult = new ApiResult<List<EmergencySettingTable>>();
try
{
Emergency_Setting_tables = await backendRepository.GetAllAsync<EmergencySettingTable>($@"
select v.system_key big_setting_name,* from emergency_setting es left join variable v on es.big_setting = v.id
where es.big_setting = {selectsetting} and es.deleted = 0 ");
apiResult.Code = "0000";
apiResult.Data = Emergency_Setting_tables;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + selectsetting);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
[HttpPost]
public async Task<ApiResult<SaveGrouping>> GetOnesetting(int selectsetting)
{
ApiResult<SaveGrouping> apiResult = new ApiResult<SaveGrouping>();
try
{
var sql = $@"select v.system_priority as priority,v.system_key as name,s.system_value verify
from variable v
left join variable s on v.id = s.system_parent_id
where v.id = {selectsetting} and v.deleted = 0";
var group = await backendRepository.GetOneAsync<SaveGrouping>(sql);
apiResult.Data = group;
apiResult.Code = "0000";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + selectsetting);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> DeletedOneSubSetting(string guid)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
await backendRepository.DeleteOne(guid, "emergency_setting", "emergency_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<EmergencySetting>> GetOneSubSetting(string guid)
{
ApiResult<EmergencySetting> apiResult = new ApiResult<EmergencySetting>();
try
{
var SubSetting = await backendRepository.GetOneAsync<EmergencySetting>("emergency_setting", $"emergency_guid = '{guid}'");
apiResult.Data = SubSetting;
apiResult.Code = "0000";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> SaveAndOpenSimulationExercise(Eventpost eventpost)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
var newguid = Guid.NewGuid();
var dictionary = new Dictionary<string, object>()
{
{"@emergency_event_guid",newguid},
{"@disaster",eventpost.disaster},
{"@building_guid", eventpost.build},
{"@type",eventpost.type}
};
await backendRepository.AddOneByCustomTable(dictionary, "emergency_event");
apiResult.Data = newguid.ToString();
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
catch(Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(eventpost);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<List<SaveGrouping>>> GetBigsetting(int disaster)
{
ApiResult<List<SaveGrouping>> apiResult = new ApiResult<List<SaveGrouping>>();
try
{
var sql = $@"
select
v.id id,
v.system_key name,
f.system_value verify
from variable v
join variable f on v.id = f.system_parent_id and f.system_type = 'Verify'
where v.system_type = 'DisasterSetting'
and v.system_parent_id = '{disaster}'
and v.deleted = 0
order by v.system_priority";
var list = await backendRepository.GetAllAsync<SaveGrouping>(sql);
apiResult.Data = list;
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + disaster);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<List<EmergencySettingTable>>> GetEmergencySetting(int selectsetting)
{
List<EmergencySettingTable> Emergency_Setting_tables = new List<EmergencySettingTable>();
ApiResult<List<EmergencySettingTable>> apiResult = new ApiResult<List<EmergencySettingTable>>();
try
{
Emergency_Setting_tables = await backendRepository.GetAllAsync<EmergencySettingTable>($@"
select v.system_key big_setting_name,* from emergency_setting es left join variable v on es.big_setting = v.id
where es.big_setting = {selectsetting} and es.deleted = 0 order by es.priority");
apiResult.Code = "0000";
apiResult.Data = Emergency_Setting_tables;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + selectsetting);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<EmergencyitemWithguid>> GetContentAndMakeItem(Emergencyitempost post)
{
ApiResult<EmergencyitemWithguid> apiResult = new ApiResult<EmergencyitemWithguid>();
try
{
var Emergency_Setting_tables = await backendRepository.GetOneAsync<EmergencyitemWithguid>($@"
select v.system_key big_setting_name,* from emergency_setting es left join variable v on es.big_setting = v.id
where es.emergency_guid = '{post.emergency_guid}'");
if(post.make_item == 1)
{
var haveguid = await backendRepository.GetOneAsync<string>($"select emergency_item_guid from emergency_item where event_guid = '{post.event_guid}' and big_setting = '{post.big_setting}' and step_setting = '{post.step_setting}'");
if(haveguid == null)
{
var newguid = Guid.NewGuid();
var dictionary = new Dictionary<string, object>()
{
{"@emergency_item_guid",newguid},
{"@event_guid",post.event_guid},
{"@big_setting", post.big_setting},
{"@step_setting",post.step_setting},
{"@created_by",myUserInfo.Userinfo_guid }
};
await backendRepository.AddOneByCustomTable(dictionary, "emergency_item");
Emergency_Setting_tables.emergency_item_guid = newguid.ToString();
}
else
{
Emergency_Setting_tables.emergency_item_guid = haveguid;
}
}
apiResult.Code = "0000";
apiResult.Data = Emergency_Setting_tables;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> NextStep (Itempost item)
{
ApiResult<string> apiResult = new ApiResult<string>();
byte finish = 0;
if(item.choose == 0)
{
finish = 1;
}else
{
finish = 2;
}
try
{
var dictionary = new Dictionary<string, object>()
{
{"@finished",finish},
{"@updated_by", myUserInfo.Userinfo_guid},
{"@updated_at", DateTime.Now}
};
if(item.choose == 1)
{
dictionary.Add("@reason", item.reason );
}
await backendRepository.UpdateOneByCustomTable(dictionary, "emergency_item", $"emergency_item_guid = '{item.eventguid}'");
apiResult.Code = "0000";
apiResult.Msg = "更新成功";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(item);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ActionResult> Dohistorytotable (string eventguid)
{
List<Eventitem> eventitems = new List<Eventitem>();
ApiResult<List<Eventitem>> apiResult = new ApiResult<List<Eventitem>>();
try
{
eventitems = await backendRepository.GetAllAsync<Eventitem>($"select * from emergency_item where event_guid = @Guid",new { Guid = $"{eventguid}" });
apiResult.Data = eventitems;
apiResult.Code = "0000";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + eventguid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
[HttpPost]
public async Task<ApiResult<bool>> CheckVerifybool(string pass)
{
ApiResult<bool> apiResult = new ApiResult<bool>();
try
{
EDFunction edFunction = new EDFunction();
string passto = "";
if (pass != null)
{
passto = edFunction.GetSHA256Encryption(pass);
}
var Verify = await backendRepository.GetAllAsync<string>("userinfo", $" role_guid = 'B0556AD7-C1E1-47A1-A1F1-802E22714B33' and password = '{passto}'");
if(Verify.Count == 0)
{
apiResult.Data = false;
}
else
{
apiResult.Data = true;
}
apiResult.Code = "0000";
}
catch (Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + pass);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
}
}

View File

@ -0,0 +1,37 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class HomeController : MybaseController<HomeController>
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}

View File

@ -0,0 +1,151 @@
using Backend.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class LoginController : Controller
{
private readonly ILogger<LoginController> logger;
private readonly IUserInfoRepository userInfoRepository;
public LoginController(ILogger<LoginController> logger,
IUserInfoRepository userInfoRepository)
{
this.logger = logger;
this.userInfoRepository = userInfoRepository;
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// 表單post提交準備登入
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> IndexAsync(LoginViewModel login)
{
if (!ModelState.IsValid)
{
return View();
}
UserInfo userInfo = null;
EDFunction edFunction = new EDFunction();
try
{
userInfo = await userInfoRepository.GetOneByAccountAsync<UserInfo>(login.Account);
if (userInfo == null)
{
ViewBag.errMsg = "帳號或密碼輸入錯誤";
return View();
}
string SHA256Pwd = edFunction.GetSHA256Encryption(login.Password);
if (string.Compare(userInfo.Password, SHA256Pwd) != 0)
{
ViewBag.errMsg = "帳號或密碼輸入錯誤";
return View();
}
}
catch (Exception ex)
{
ViewBag.ErrMsg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(login);
logger.LogError("【Login/Index - 登入資訊】" + json);
logger.LogError("【Login/Index】" + ex.Message);
return View();
}
HttpContext.Session.SetString("MyAccount", edFunction.AESEncrypt(userInfo.Account)); //將帳號透過AES加密
return RedirectToAction("Index", "Home");
}
/// <summary>
/// 登出Action 記得別加上[Authorize]不管用戶是否登入都可以執行SignOut
/// </summary>
/// <returns></returns>
public IActionResult SignOut()
{
HttpContext.Session.Clear();
return RedirectToAction("Index", "Login");//導至登入頁
}
/// <summary>
/// 忘記密碼
/// </summary>
/// <returns></returns>
public IActionResult ForgotPassword()
{
return View("~/Views/Login/ForgotPassword.cshtml");
}
/// <summary>
/// 取得新密碼
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> ForgotPasswordAsync(ForgotPasswordViewModel forgot)
{
if (!ModelState.IsValid)
{
return View();
}
string sWhere = @"deleted = @Deleted AND email = @Email";
object param = new { Deleted = 0, Email = forgot.Email };
var user = await userInfoRepository.GetOneAsync<UserInfo>("userinfo", sWhere, param);
if (user == null)
{
ViewBag.errMsg = "查無此信箱";
return View();
}
//隨機產生亂數
Random random = new Random((int)DateTime.Now.Ticks);
const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
string random_password = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(chars.Length)]).ToArray());
EDFunction edFunction = new EDFunction();
var newPassword = edFunction.GetSHA256Encryption(random_password);
Dictionary<string, object> updateUserPasswordDic = new Dictionary<string, object>()
{
{ "@password", newPassword},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
await userInfoRepository.UpdateOneByCustomTable(updateUserPasswordDic, "userinfo", "userinfo_guid='" + user.Userinfo_guid + "'");
//var sendSubject = "變更密碼成功";
//var sendContent = $"您的新密碼為:{random_password}";
//List<string> recipientEmails = new List<string>()
//{
// user.Email
//};
//sendEmailService.Send(recipientEmails, sendSubject, sendContent);
return RedirectToAction("Index", "Login");
}
}
}

View File

@ -0,0 +1,101 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Repository.BackendRepository.Interface;
using Backend.Models;
using Backend.Services.Implement;
namespace Backend.Controllers
{
public class MybaseController<T> : Controller where T : MybaseController<T>
{
private ILogger<T> _logger;
protected ILogger<T> Logger => _logger ?? (_logger = HttpContext?.RequestServices.GetService<ILogger<T>>());
private IBackendRepository backendRepository => HttpContext?.RequestServices.GetService<IBackendRepository>();
private IUserInfoRepository userInfoRepository => HttpContext?.RequestServices.GetService<IUserInfoRepository>();
public string baseURL => HttpContext?.Request.Scheme + "://" + HttpContext?.Request.Host + "/";
public BackgroundService backgroundService;
protected MyUserInfo myUserInfo = null;
public string controllerName;
public string actionName;
public MybaseController() { }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
EDFunction edFunction = new EDFunction();
var myAccount = edFunction.AESDecrypt(HttpContext.Session.GetString("MyAccount"));
controllerName = ControllerContext.RouteData.Values["controller"].ToString(); //controller名稱
actionName = ControllerContext.RouteData.Values["action"].ToString(); //action名稱
bool isAjaxCall = filterContext.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
if (string.IsNullOrEmpty(myAccount))
{
if (isAjaxCall)
{
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 499;
return;
}
else
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{"controller", "Login"},
{"action", "Index"}
});
return;
}
}
backgroundService = new BackgroundService(backendRepository);
//取得當前登入使用者資訊
myUserInfo = userInfoRepository.GetMyUserInfoByAccount<MyUserInfo>(myAccount);
var showview = backendRepository.GetAllAsync<string>($@"select ap.ShowView from userinfo us
left join role_auth ra on ra.role_guid = us.role_guid
left join auth_page ap on ap.AuthCode = ra.AuthCode
where us.userinfo_guid = '{myUserInfo.Userinfo_guid}'");
myUserInfo.ShowView = showview.Result;
ViewBag.myUserInfo = myUserInfo;
ViewBag.role = showview.Result;
#region
var content = JsonConvert.SerializeObject(filterContext.ActionArguments);
var parameter = content.CompareTo("{}") == 0 ? null : content;
List<string> removeParam = new List<string>() { "ChangePassword" }; //移除不紀錄參數的actionName
if (removeParam.Any(x => actionName.Contains(x)))
{
parameter = "{}";
}
Dictionary<string, object> operatorLog = new Dictionary<string, object>();
operatorLog = new Dictionary<string, object>()
{
{ "@controller_name", controllerName},
{ "@action_name", actionName},
{ "@parameter", parameter},
{ "@created_by", myUserInfo.Userinfo_guid}
};
backendRepository.InsertOperatorLog(operatorLog, "operation_back_log");
//operatorLogRepository.Add(operatorLog, properties);
#endregion
}
}
}

View File

@ -0,0 +1,7 @@
namespace Backend.Controllers
{
internal class NpoiMemoryStream
{
public bool AllowClose { get; set; }
}
}

View File

@ -0,0 +1,366 @@
using Backend.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class RescueDeviceController : MybaseController<RescueDeviceController>
{
private readonly IBackendRepository backendRepository;
public RescueDeviceController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult FireExtinguisher()
{
return View();
}
public IActionResult AED()
{
return View();
}
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> GetFloorByBuild (string Building)
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
List<KeyValue> KeyValue = new List<KeyValue>();
try
{
var sqlString = @$"select floor_guid as Value, full_name as Name from floor a where a.deleted = 0 and a.building_guid = '{Building}' and a.status = 0 order by a.priority";
KeyValue = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = KeyValue;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ActionResult> RescueDeviceTable(RescueDeviceTableUse post)
{
List<RescueDeviceTable> RescueDeviceTables = new List<RescueDeviceTable>();
ApiResult<List<RescueDeviceTable>> apiResult = new ApiResult<List<RescueDeviceTable>>();
try
{
RescueDeviceTables = await backendRepository.GetAllAsync<RescueDeviceTable>("rescue_device", $"building_guid = '{post.build}' and floor_guid in @floors and rescue_device_kind = {post.kind}", new { floors = post.floors }, "floor_name");
apiResult.Code = "0000";
apiResult.Data = RescueDeviceTables;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
var result = Json(new
{
data = apiResult
});
return result;
}
[HttpPost]
public async Task<ApiResult<string>> ImportRescueDevice(ImportRescueDevice import)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
IWorkbook workbook;
var filename_ext = Path.GetExtension(import.import_file.FileName).ToLower();
if (filename_ext == ".xls")
{
workbook = new HSSFWorkbook(import.import_file.OpenReadStream());
}
else if (filename_ext == ".xlsx")
{
workbook = new XSSFWorkbook(import.import_file.OpenReadStream());
}
else
{
workbook = null;
}
if (workbook == null)
{
apiResult.Code = "9998";
apiResult.Msg = $"{import.import_file.FileName}該檔案失效,請重新操作。";
return apiResult;
}
var sqlString = @$"select floor_guid as Value, full_name as Name from floor a where a.deleted = 0 and a.building_guid = '{import.building}' and a.status = 0 order by a.priority";
var floor = await backendRepository.GetAllAsync<KeyValue>(sqlString);
List<Dictionary<string, object>> deviceImports = new List<Dictionary<string, object>>();
var sheet = workbook.GetSheetAt(0);
IRow header = sheet.GetRow(sheet.FirstRowNum);
ICell cell = header.GetCell(1);
if(!string.IsNullOrEmpty(cell.ToString()) && cell.ToString()!= "設備編號")
{
apiResult.Code = "9998";
apiResult.Msg = $"{import.import_file.FileName}該檔案格式錯誤,請重新操作。";
return apiResult;
}
cell = header.GetCell(0);
if (!string.IsNullOrEmpty(cell.ToString()) && cell.ToString() != "樓層")
{
apiResult.Code = "9998";
apiResult.Msg = $"{import.import_file.FileName}該檔案格式錯誤,請重新操作。";
return apiResult;
}
cell = header.GetCell(2);
if (!string.IsNullOrEmpty(cell.ToString()) && cell.ToString() != "位置")
{
apiResult.Code = "9998";
apiResult.Msg = $"{import.import_file.FileName}該檔案格式錯誤,請重新操作。";
return apiResult;
}
List<int> columns = new List<int>();
for(var a = sheet.FirstRowNum + 1;a <= sheet.LastRowNum; a++)
{
var floorname = sheet.GetRow(a).GetCell(0).ToString();
var floorguid = floor.Where(k => k.Name.ToString() == floorname).Select(d =>d.Value).FirstOrDefault();
if(floorguid == null)
{
apiResult.Code = "9998";
apiResult.Msg = $"{import.import_file.FileName}該檔案樓層名稱錯誤,請確認後重新操作。";
return apiResult;
}
Dictionary<string, object> deviceImport = new Dictionary<string, object>();
deviceImport.Add("@rescue_device_guid", Guid.NewGuid().ToString());
deviceImport.Add("@rescue_device_id", sheet.GetRow(a).GetCell(1).ToString());
deviceImport.Add("@floor_guid", floorguid);
deviceImport.Add("@floor_name", sheet.GetRow(a).GetCell(0).ToString());
deviceImport.Add("@location", sheet.GetRow(a).GetCell(2).ToString());
deviceImport.Add("@rescue_device_kind", import.kind);
deviceImport.Add("@building_guid", import.building);
deviceImport.Add("@created_by", myUserInfo.Userinfo_guid);
deviceImport.Add("@created_at", DateTime.Now);
deviceImports.Add(deviceImport);
}
await backendRepository.PurgeOneByGuidWithCustomDBNameAndTable("rescue_device", $"building_guid = '{import.building}' and rescue_device_kind = {import.kind}");
await backendRepository.AddMutiByCustomTable(deviceImports, "rescue_device");
apiResult.Code = "0000";
apiResult.Msg = "匯入成功";
}
catch(Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> DeletedIt(string guid)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
await backendRepository.PurgeOneAsync(guid, "rescue_device", "rescue_device_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch(Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<RescueDevice>> GetLocation (string guid)
{
ApiResult<RescueDevice> apiResult = new ApiResult<RescueDevice>();
try
{
var location = await backendRepository.GetOneAsync<RescueDevice>("rescue_device", $"rescue_device_guid = '{guid}'");
if(location == null)
{
apiResult.Code = "9998";
apiResult.Msg = "資料不存在,請重新操作";
}
else
{
apiResult.Code = "0000";
apiResult.Data = location;
}
}
catch(Exception ex)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + ex.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> SaveFireExtinguisher(SaveFireExtinguisher save)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
var a = new Dictionary<string, object>()
{
{"@location",save.location}
};
await backendRepository.UpdateOneByCustomTable(a, "rescue_device", $"rescue_device_guid = '{save.guid}'");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】");
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
public FileResult ExportExcel(string post)
{
var postObject = JsonConvert.DeserializeObject<Excel>(post);
var workbook = new XSSFWorkbook();
#region excel設定
IFont font12 = workbook.CreateFont();
font12.FontName = "新細明體";
font12.FontHeightInPoints = 12;
ICellStyle style12 = workbook.CreateCellStyle();
style12.SetFont(font12);
style12.Alignment = HorizontalAlignment.Center;
style12.VerticalAlignment = VerticalAlignment.Center;
IFont font12Times = workbook.CreateFont();
font12Times.FontName = "Times New Roman";
font12Times.FontHeightInPoints = 12;
IFont font18 = workbook.CreateFont();
font18.FontName = "新細明體";
font18.FontHeightInPoints = 18;
font18.IsBold = true;
ICellStyle styleTitle18 = workbook.CreateCellStyle();
styleTitle18.SetFont(font18);
styleTitle18.Alignment = HorizontalAlignment.Center;
styleTitle18.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLeft12 = workbook.CreateCellStyle();
styleLeft12.SetFont(font12);
styleLeft12.Alignment = HorizontalAlignment.Left;
styleLeft12.VerticalAlignment = VerticalAlignment.Center;
ICellStyle styleLine12 = workbook.CreateCellStyle();
styleLine12.SetFont(font12);
styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
styleLine12.VerticalAlignment = VerticalAlignment.Center;
styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
ICellStyle stylein12 = workbook.CreateCellStyle();
stylein12.SetFont(font12Times);
stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
stylein12.VerticalAlignment = VerticalAlignment.Center;
stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
stylein12.WrapText = true;
#endregion
var devicename = "";
if (postObject.kind == 0)
{
devicename = "滅火器";
}
else
{
devicename = "AED";
}
var sheet = workbook.CreateSheet(devicename);
var RescueDevices = backendRepository.GetAllAsync<RescueDevice>("rescue_device", $"building_guid = '{postObject.build}' and rescue_device_kind = {postObject.kind}",null, "floor_name");
int RowPosition = 0;
IRow row = sheet.CreateRow(RowPosition);
ICell cell = row.CreateCell(1);
sheet.SetColumnWidth(0, 4 * 160 * 12);
sheet.SetColumnWidth(1, 4 * 160 * 12);
sheet.SetColumnWidth(2, 4 * 160 * 12);
cell.SetCellValue("設備編號");
cell.CellStyle = styleLine12;
cell = row.CreateCell(0);
cell.SetCellValue("樓層");
cell.CellStyle = styleLine12;
cell = row.CreateCell(2);
cell.SetCellValue("位置");
cell.CellStyle = styleLine12;
foreach(var device in RescueDevices.Result)
{
RowPosition += 1;
row = sheet.CreateRow(RowPosition);
for(var a = 0 ; a < 3 ; a++)
{
cell = row.CreateCell(a);
if (a == 1)
{
cell.SetCellValue(device.rescue_device_id);
}
if (a == 0)
{
cell.SetCellValue(device.floor_name);
}
if (a == 2)
{
cell.SetCellValue(device.location);
}
cell.CellStyle = style12;
}
}
var ms = new NpoiMemoryStream
{
AllowClose = false
};
workbook.Write(ms);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
return File(ms, "application/vnd.ms-excel", postObject.buildname + "-" + devicename + ".xlsx");
}
}
}

View File

@ -0,0 +1,173 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class ServicePlanController : MybaseController<ServicePlanController>
{
private readonly IBackendRepository backendRepository;
public ServicePlanController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
public async Task<ApiResult<string>> SavePlan (BackgroundServicePlan plan)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
if (plan.Id == 0)
{
Dictionary<string, object> Plan = new Dictionary<string, object>()
{
{ "@status", plan.status},
{ "@plan_name", plan.Plane_name},
{ "@building_guid", plan.building_guid},
{ "@target_table", plan.Target_table},
{ "@execution_time", plan.Execution_time},
{ "@execution_type", plan.Execution_type},
{ "@start_time", plan.Start_time}
};
if(plan.End_time == "0001-01-01 00:00:00")
{
Plan.Add("@end_time", null);
}
else
{
Plan.Add("@end_time", plan.End_time);
}
await backendRepository.AddOneByCustomTable(Plan, "background_service_plan");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
Dictionary<string, object> Plan = new Dictionary<string, object>()
{
{ "@status", plan.status},
{ "@plan_name", plan.Plane_name},
{ "@building_guid", plan.building_guid},
{ "@target_table", plan.Target_table},
{ "@execution_time", plan.Execution_time},
{ "@execution_type", plan.Execution_type},
{ "@start_time", plan.Start_time}
};
if (plan.End_time == "0001-01-01 00:00:00")
{
Plan.Add("@end_time", null);
}
else
{
Plan.Add("@end_time", plan.End_time);
}
await backendRepository.UpdateOneByCustomTable(Plan, "background_service_plan", "id='" + plan.Id + "'");
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(plan);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
public async Task<ApiResult<List<PlanTable>>> GetPlanTable()
{
ApiResult<List<PlanTable>> apiResult = new ApiResult<List<PlanTable>>();
try
{
var plans = await backendRepository.GetAllAsync<PlanTable>("select bsp.*,b.full_name building from background_service_plan bsp left join building b on bsp.building_guid = b.building_guid where bsp.deleted = 0 order by bsp.id desc");
foreach(var plan in plans)
{
var timetype = plan.Execution_type switch
{
0 => "分",
1 => "小時",
2 => "天",
3 => "週",
4 => "月",
_ => "",
};
plan.execution = "每" + plan.Execution_time + timetype;
plan.time = plan.Start_time + @"<br>-<br>";
if(plan.End_time != "0001-01-01 00:00:00")
{
plan.time += plan.End_time;
}
}
apiResult.Code = "0000";
apiResult.Data = plans;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
public async Task<ApiResult<BackgroundServicePlan>> GetonePlan (int id)
{
ApiResult<BackgroundServicePlan> apiResult = new ApiResult<BackgroundServicePlan>();
try
{
var plan = await backendRepository.GetOneAsync<BackgroundServicePlan>("background_service_plan", $" id = {id}");
apiResult.Data = plan;
apiResult.Code = "0000";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + id);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> DeletePlan(int id)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
await backendRepository.DeleteOne(id.ToString(), "background_service_plan", "id");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "id=" + id);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
}
}

View File

@ -0,0 +1,804 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class SystemCategoryController : MybaseController<SystemCategoryController>
{
private readonly IBackendRepository backendRepository;
public SystemCategoryController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// 取得系統大類清單
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<SystemMain>>> SystemMainList()
{
ApiResult<List<SystemMain>> apiResult = new ApiResult<List<SystemMain>>();
try
{
var sWhere = "deleted = 0";
var systemMainList = await backendRepository.GetAllAsync<SystemMain>("main_system", sWhere, null, "priority ASC, created_at DESC");
apiResult.Code = "0000";
apiResult.Data = systemMainList;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 取得單一系統大類
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<SystemMain>> GetOneSystemMain(string guid)
{
ApiResult<SystemMain> apiResult = new ApiResult<SystemMain>();
try
{
string sWhere = @$"deleted = @Deleted AND main_system_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var systemMain = await backendRepository.GetOneAsync<SystemMain>("main_system", sWhere, param);
apiResult.Code = "0000";
apiResult.Data = systemMain;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 新增 / 修改 系統大類資料
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> SaveSystemMain(SystemMain post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = @Deleted AND main_system_guid = @Guid";
object param = new { Deleted = 0, Guid = post.Main_system_guid };
var systemMain = await backendRepository.GetOneAsync<SystemMain>("main_system", sWhere, param);
if (systemMain == null)
{
//新增
//產生一組GUID
var guid = Guid.NewGuid(); //系統大類GUID
Dictionary<string, object> systemMainDic = new Dictionary<string, object>()
{
{ "@main_system_guid", guid},
{ "@full_name", post.Full_name},
{ "@code", post.Code},
{ "@created_by", myUserInfo.Userinfo_guid}
};
await backendRepository.AddOneByCustomTable(systemMainDic, "main_system");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
Dictionary<string, object> systemMainDic = new Dictionary<string, object>()
{
{ "@full_name", post.Full_name},
{ "@code", post.Code},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
await backendRepository.UpdateOneByCustomTable(systemMainDic, "main_system", "main_system_guid='" + systemMain.Main_system_guid + "'");
var AuthCodes = await backendRepository.GetAllAsync<string>(
@$"select AuthCode from auth_page ap
join sub_system ss on ss.sub_system_guid = ap.ShowView
join main_system ms on ms.main_system_guid = ss.main_system_guid
where ms.main_system_guid = '{systemMain.Main_system_guid}'");
if(AuthCodes.Count > 0)
{
await backendRepository.ExecuteSql($@"UPDATE auth_page
SET MainName = '{post.Full_name}'
WHERE AuthCode IN @authCode;",new { authCode = AuthCodes });
}
#region
var auth_Pages = await backendRepository.GetAllAsync<Auth_page>("auth_page", "");
List<Dictionary<string, object>> authPagesDics = new List<Dictionary<string, object>>();
foreach (var auth_page in auth_Pages)
{
Dictionary<string, object> authPagesDic = new Dictionary<string, object>()
{
{ "@AuthCode", auth_page.AuthCode},
{ "@AuthType", auth_page.AuthType},
{ "@MainName", auth_page.MainName},
{ "@SubName", auth_page.SubName},
{ "@building_guid", auth_page.building_guid},
{ "@ShowView", auth_page.ShowView},
{ "@created_at", auth_page.created_at},
};
authPagesDics.Add(authPagesDic);
}
await backendRepository.ManualInsertBackgroundServiceTask("", "", "auth_page", "purge_all_insert", authPagesDics);
#endregion
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 刪除單一系統大類
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> DeleteOneSystemMain(string guid)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = @Deleted AND main_system_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var systemMain = await backendRepository.GetOneAsync<SystemMain>("main_system", sWhere, param);
if (systemMain == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該系統大類";
return apiResult;
}
//檢查是否有未刪除的區域選單
var sbuildMenu = $@"SELECT
b.full_name
FROM building_menu bm
LEFT JOIN building b ON bm.building_guid = b.building_guid AND b.deleted = 0
WHERE bm.main_system_guid = @Guid
GROUP BY b.full_name";
var buildMenus = await backendRepository.GetAllAsync<string>(sbuildMenu, new { Guid = guid });
if (buildMenus.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "區域選單中尚有棟別正在使用該系統大類,故無法刪除";
apiResult.Data = string.Join("<br>", buildMenus);
return apiResult;
}
//檢查底下是否有未刪除的系統小類
string sSubWhere = @$"deleted = @Deleted AND main_system_guid = @Guid";
object sub_param = new { Deleted = 0, Guid = systemMain.Main_system_guid };
var systemSubs = await backendRepository.GetAllAsync<SystemSub>("sub_system", sWhere, param);
if (systemSubs.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "系統小類中尚有小類正在使用系統大類,故無法刪除";
apiResult.Data = string.Join("<br>", systemSubs.Select(x => x.Full_name).ToList());
return apiResult;
}
await backendRepository.DeleteOne(guid, "main_system", "main_system_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "main_system_guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 取得系統小類清單
/// </summary>
/// <param name="main_system_guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<SystemSub>>> SystemSubList(string main_system_guid)
{
ApiResult<List<SystemSub>> apiResult = new ApiResult<List<SystemSub>>();
try
{
var sWhere = @"deleted = @Deleted AND main_system_guid = @Main_system_guid";
object param = new { Deleted = 0, Main_system_guid = main_system_guid };
var systemSubs = await backendRepository.GetAllAsync<SystemSub>("sub_system", sWhere, param, "priority ASC, created_at DESC");
apiResult.Code = "0000";
apiResult.Data = systemSubs;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 取得單一系統小類
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<SystemSub>> GetOneSystemSub(string guid)
{
ApiResult<SystemSub> apiResult = new ApiResult<SystemSub>();
try
{
string sWhere = @$"deleted = @Deleted AND sub_system_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var systemSub = await backendRepository.GetOneAsync<SystemSub>("sub_system", sWhere, param);
apiResult.Code = "0000";
apiResult.Data = systemSub;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 新增 / 修改 系統小類資料
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> SaveSystemSub(SystemSub post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = @Deleted AND sub_system_guid = @Guid";
object param = new { Deleted = 0, Guid = post.Sub_system_guid };
var systemSub = await backendRepository.GetOneAsync<SystemSub>("sub_system", sWhere, param);
if (systemSub == null)
{
//新增
//產生一組GUID
var guid = Guid.NewGuid(); //GUID
Dictionary<string, object> systemSubDic = new Dictionary<string, object>()
{
{ "@sub_system_guid", guid},
{ "@main_system_guid", post.Main_system_guid},
{ "@full_name", post.Full_name},
{ "@created_by", myUserInfo.Userinfo_guid}
};
await backendRepository.AddOneByCustomTable(systemSubDic, "sub_system");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
Dictionary<string, object> systemSubDic = new Dictionary<string, object>()
{
{ "@full_name", post.Full_name},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
await backendRepository.UpdateOneByCustomTable(systemSubDic, "sub_system", "sub_system_guid='" + systemSub.Sub_system_guid + "'");
var AuthCodes = await backendRepository.GetAllAsync<string>(
@$"select AuthCode from auth_page ap
where ap.ShowView = '{systemSub.Sub_system_guid}'");
if (AuthCodes.Count > 0)
{
await backendRepository.ExecuteSql($@"UPDATE auth_page
SET SubName = '{post.Full_name}'
WHERE AuthCode IN @authCode;", new { authCode = AuthCodes });
}
#region
var auth_Pages = await backendRepository.GetAllAsync<Auth_page>("auth_page", "");
List<Dictionary<string, object>> authPagesDics = new List<Dictionary<string, object>>();
foreach (var auth_page in auth_Pages)
{
Dictionary<string, object> authPagesDic = new Dictionary<string, object>()
{
{ "@AuthCode", auth_page.AuthCode},
{ "@AuthType", auth_page.AuthType},
{ "@MainName", auth_page.MainName},
{ "@SubName", auth_page.SubName},
{ "@building_guid", auth_page.building_guid},
{ "@ShowView", auth_page.ShowView},
{ "@created_at", auth_page.created_at},
};
authPagesDics.Add(authPagesDic);
}
await backendRepository.ManualInsertBackgroundServiceTask("", "", "auth_page", "purge_all_insert", authPagesDics);
#endregion
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 刪除單一系統小類
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> DeleteOneSystemSub(string guid)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = @Deleted AND sub_system_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var systemSub = await backendRepository.GetOneAsync<SystemSub>("sub_system", sWhere, param);
if (systemSub == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該系統小類";
return apiResult;
}
//檢查是否有未刪除的區域選單
var sbuildMenu = $@"SELECT
CONCAT(b.full_name, ' - ', ms.full_name)
FROM building_menu bm
LEFT JOIN building b ON bm.building_guid = b.building_guid AND b.deleted = 0
LEFT JOIN main_system ms ON bm.main_system_guid = ms.main_system_guid AND ms.deleted = 0
WHERE bm.sub_system_guid = @Guid";
var buildMenus = await backendRepository.GetAllAsync<string>(sbuildMenu, new { Guid = guid });
if (buildMenus.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "區域選單中尚有選單正在使用該系統小類,故無法刪除";
apiResult.Data = string.Join("<br>", buildMenus);
return apiResult;
}
//檢查是否有未刪除的系統小類樓層
var ssubSystemFloor = $@"SELECT
CONCAT(b.full_name, ' - ', ms.full_name, ' - ', ss.full_name, ' - ', f.full_name)
FROM sub_system_floor ssf
LEFT JOIN building b ON ssf.building_guid = b.building_guid AND b.deleted = 0
LEFT JOIN main_system ms ON ssf.main_system_guid = ms.main_system_guid AND ms.deleted = 0
LEFT JOIN sub_system ss ON ssf.sub_system_guid = ss.sub_system_guid AND ss.deleted = 0
LEFT JOIN floor f ON ssf.floor_guid = f.floor_guid AND f.deleted = 0
WHERE ssf.sub_system_guid = @Guid
AND ssf.deleted = 0";
var subSystemFloor = await backendRepository.GetAllAsync<string>(sbuildMenu, new { Guid = guid });
if (subSystemFloor.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "區域選單中尚有樓層正在使用該系統小類,故無法刪除";
apiResult.Data = string.Join("<br>", subSystemFloor);
return apiResult;
}
//檢查是否有未刪除的設備項目
var sdeviceItem = $@"SELECT
di.full_name
FROM device_item di
WHERE di.deleted = 0
AND di.sub_system_guid = @Guid";
var deviceItems = await backendRepository.GetAllAsync<string>(sdeviceItem, new { Guid = guid });
if (deviceItems.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "設備項目中尚有項目正在使用該系統小類,故無法刪除";
apiResult.Data = string.Join("<br>", deviceItems);
return apiResult;
}
await backendRepository.DeleteOne(guid, "sub_system", "sub_system_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "sub_system_guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> Savedevice_item(Device_item device_Item)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
//檢查是否有未刪除的區域選單
if(device_Item.is_show_riserDiagram == 1)
{
var sql_show_riserDiagram = $@"SELECT * FROM device_item di
WHERE di.sub_system_guid = @SubSystemGuid AND di.deleted = 0 AND is_show_riserDiagram = 1";
var is_show_riserDiagram = await backendRepository.GetAllAsync<string>(sql_show_riserDiagram, new { SubSystemGuid = device_Item.sub_system_guid });
if (is_show_riserDiagram.Count() > 0)
{
apiResult.Code = "9998";
apiResult.Msg = "請先取消已選擇顯示於昇位圖點位。";
return apiResult;
}
}
if (device_Item.device_item_guid == null)
{
//新增
//產生一組GUID
var guid = Guid.NewGuid(); //GUID
Dictionary<string, object> Device_itemDic = new Dictionary<string, object>()
{
{ "@device_item_guid", guid},
{ "@sub_system_guid", device_Item.sub_system_guid},
{ "@full_name", device_Item.full_name},
{ "@points", device_Item.points},
{ "@unit", device_Item.unit},
{ "@is_show", device_Item.is_show},
{ "@is_show_riserDiagram", device_Item.is_show_riserDiagram},
{ "@is_controll", device_Item.is_controll},
{ "@is_bool", device_Item.is_bool},
{ "@created_by", myUserInfo.Userinfo_guid},
};
await backendRepository.AddOneByCustomTable(Device_itemDic, "device_item");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
Dictionary<string, object> Device_itemDic = new Dictionary<string, object>()
{
{ "@sub_system_guid", device_Item.sub_system_guid},
{ "@full_name", device_Item.full_name},
{ "@points", device_Item.points},
{ "@unit", device_Item.unit},
{ "@is_show", device_Item.is_show},
{ "@is_show_riserDiagram", device_Item.is_show_riserDiagram},
{ "@is_controll", device_Item.is_controll},
{ "@is_bool", device_Item.is_bool},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
await backendRepository.UpdateOneByCustomTable(Device_itemDic, "device_item", "device_item_guid='" + device_Item.device_item_guid + "'");
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(device_Item);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<List<Device_item>>> DeviceItemTable(string sub_system_guid)
{
ApiResult<List<Device_item>> apiResult = new ApiResult<List<Device_item>>();
try
{
var sWhere = @"deleted = @Deleted AND sub_system_guid = @Sub_system_guid";
object param = new { Deleted = 0, Sub_system_guid = sub_system_guid };
var systemSubs = await backendRepository.GetAllAsync<Device_item>("device_item", sWhere, param, "created_at DESC");
apiResult.Code = "0000";
apiResult.Data = systemSubs;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<Device_item>> GetOneDeviceItem(string guid)
{
ApiResult<Device_item> apiResult = new ApiResult<Device_item>();
try
{
string sWhere = @$"deleted = @Deleted AND device_item_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var Deviceitem = await backendRepository.GetOneAsync<Device_item>("device_item", sWhere, param);
apiResult.Code = "0000";
apiResult.Data = Deviceitem;
}
catch (Exception exception)
{
apiResult.Code = "9999";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
[HttpPost]
public async Task<ApiResult<string>> DeleteOneSystemSubDeviceItem(string guid)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = @Deleted AND device_item_guid = @Guid";
object param = new { Deleted = 0, Guid = guid };
var device_Item = await backendRepository.GetOneAsync<Device_item>("device_item", sWhere, param);
if (device_Item == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該設備項目";
return apiResult;
}
await backendRepository.DeleteOne(guid, "device_item", "device_item_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "device_item_guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
public async Task<ApiResult<bool>> HaveSamePoints(Checksame post)
{
ApiResult<bool> apiResult = new ApiResult<bool>();
try
{
var point = await backendRepository.GetOneAsync<Device_item>("device_item", $" sub_system_guid = '{post.sub_system_guid}' and points = '{post.points}' and device_item_guid != '{post.device_item_guid}' and deleted = 0");
if (point != null)
{
apiResult.Data = true;
}
else
{
apiResult.Data = false;
}
apiResult.Code = "0000";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
public async Task<ApiResult<Deletebool>> CheckCanDelete(guidandsubguid post)
{
ApiResult<Deletebool> apiResult = new ApiResult<Deletebool>();
try
{
var tags = await backendRepository.GetAllAsync<Tags>(
@$"select * from (select dk.device_building_tag ,dk.device_name_tag,dk.device_system_tag from device_kind dk where dk.device_normal_point_guid = '{post.guid}') dkn
union(select dk.device_building_tag, dk.device_name_tag, dk.device_system_tag from device_kind dk where dk.device_close_point_guid = '{post.guid}')
union(select dk.device_building_tag, dk.device_name_tag, dk.device_system_tag from device_kind dk where dk.device_error_point_guid = '{post.guid}')");
if (tags.Count == 0)
{
Deletebool deletebool = new Deletebool()
{
Delete = false,
Reason = ""
};
apiResult.Data = deletebool;
}
else
{
Deletebool deletebool = new Deletebool()
{
Delete = true,
Reason = ""
};
var unionsql = "";
var last = tags.Last();
foreach (var tag in tags)
{
unionsql += $@"select d.building_guid,d.main_system_guid,d.sub_system_guid,d.device_name_tag from device d where d.sub_system_guid = '{post.subguid}' and d.device_building_tag = '{tag.device_building_tag}' and d.device_system_tag = '{tag.device_system_tag}' and d.device_name_tag = '{tag.device_name_tag}' group by d.building_guid,d.main_system_guid,d.sub_system_guid,d.device_name_tag";
if (!last.Equals(tag))
{
unionsql += " union ";
}
}
var sql = @$"select ms.full_name msname,b.full_name bname,s.full_name subname,de.device_name_tag from
({unionsql}) de
left join main_system ms on ms.main_system_guid = de.main_system_guid
left join building b on b.building_guid = de.building_guid
left join sub_system s on s.sub_system_guid = de.sub_system_guid";
var names = await backendRepository.GetAllAsync<GetCheckName>(sql);
var count = 0;
foreach (var name in names)
{
count++;
deletebool.Reason += count.ToString() + "." + name.bname + "-" + name.msname + "-" + name.subname + "-" + name.device_name_tag + "<br>";
}
apiResult.Data = deletebool;
}
apiResult.Code = "0000";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
public async Task<ApiResult<Deletebool>> CheckCanSubDelete(string guid)
{
ApiResult<Deletebool> apiResult = new ApiResult<Deletebool>();
try
{
var text = "";
var item = await backendRepository.GetAllAsync<string>(@$"select device_item_guid from device_item where deleted = 0 and sub_system_guid = '{guid}'");
if(item.Count > 0)
{
text += "項目還有尚未刪除<br>";
}
var menu = await backendRepository.GetAllAsync<string>($"select sub_system_guid from building_menu where sub_system_guid = '{guid}'");
if (menu.Count > 0)
{
text += "區域選單還有尚未刪除<br>";
}
Deletebool deletebool = new Deletebool()
{
Delete = false,
Reason = ""
};
if (text != "")
{
deletebool.Delete = true;
deletebool.Reason = text;
}
else
{
deletebool.Delete = false;
}
apiResult.Data = deletebool;
apiResult.Code = "0000";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
}
}

View File

@ -0,0 +1,640 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class UserInfoController : MybaseController<UserInfoController>
{
private readonly ILogger<UserInfoController> _logger;
private readonly IBackendRepository backendRepository;
public UserInfoController(ILogger<UserInfoController> logger, IBackendRepository backendRepository)
{
_logger = logger;
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// 帳號管理列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<UserManagerList>>> UserManagerList()
{
ApiResult<List<UserManagerList>> apiResult = new ApiResult<List<UserManagerList>>();
List<UserManagerList> userManagerList = new List<UserManagerList>();
try
{
var sqlString = @$"SELECT A.userinfo_guid, A.full_name, B.full_name AS 'Role_full_name', A.email, A.phone, A.created_at,A.Account ,B.layer
FROM userinfo A
LEFT JOIN role B ON A.role_guid=B.role_guid AND B.deleted='0'
WHERE A.deleted = 0
ORDER BY A.created_at DESC";
userManagerList = await backendRepository.GetAllAsync<UserManagerList>(sqlString);
apiResult.Code = "0000";
apiResult.Data = userManagerList;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 角色管理列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<RoleManagerList>>> RoleManagerList(int post) //是否判斷layer 0:否 1:是
{
ApiResult<List<RoleManagerList>> apiResult = new ApiResult<List<RoleManagerList>>();
List<RoleManagerList> roleList = new List<RoleManagerList>();
try
{
var layersql = "";
if(post == 1)
{
layersql = "and A.layer = 1 ";
}
var sqlString = @$"SELECT *
FROM role A
WHERE A.deleted = 0 {layersql}
ORDER BY A.created_at DESC";
roleList = await backendRepository.GetAllAsync<RoleManagerList>(sqlString);
apiResult.Code = "0000";
apiResult.Data = roleList;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 新增 / 修改 使用者
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> SaveUser(SaveUserManager post)
{
ApiResult<string> apiResult = new ApiResult<string>();
UserInfo userInfo = null;
try
{
userInfo = await backendRepository.GetOneAsync<UserInfo>("userinfo", $"userinfo_guid='{post.Id.ToString()}'");
if (userInfo == null)
{
if (post.Id != "0")
{
apiResult.Code = "9998";
apiResult.Msg = "查無該使用者。";
return apiResult;
}
#region 使
//判斷帳號 是否已存在
var exist = await backendRepository.HasExistsWithGuid(post.Account, "userinfo", "account");
if (exist)
{
apiResult.Code = "9986";
apiResult.Msg = "該帳號已被註冊,請重新輸入";
return apiResult;
}
EDFunction edFunction = new EDFunction();
//隨機產生亂數密碼
Random random = new Random((int)DateTime.Now.Ticks);
const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
string random_password = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(chars.Length)]).ToArray());
var newPassword = edFunction.GetSHA256Encryption(random_password);
//產生一組GUID
var guid = Guid.NewGuid(); //使用者GUID
Dictionary<string, object> userinfo = new Dictionary<string, object>();
userinfo = new Dictionary<string, object>()
{
{ "@userinfo_guid", guid},
{ "@Full_name", post.Name},
{ "@Email", post.Email},
{ "@Account", post.Account},
{ "@Password", newPassword},
{ "@Role_guid", post.RoleId},
{ "@Phone", post.Phone},
{ "@created_by", myUserInfo.Userinfo_guid}
};
await backendRepository.AddOneByCustomTable(userinfo, "userinfo");
var sWhere = "system_type = 'website_config' AND system_key = 'website_url'";
var website_url = await backendRepository.GetOneAsync<Variable>("variable", sWhere);
var sendSubject = "新增帳號成功";
var sendContent = $@"您的新密碼為:{random_password}
<br><a href='{website_url.system_value}' target='_blank'>{website_url.system_value}</a>";
Dictionary<string, object> insertNotify = new Dictionary<string, object>()
{
{ "@task_type", 0},
{ "@recipient_name", post.Name},
{ "@recipient_phone", post.Phone},
{ "@recipient_email", post.Email},
{ "@message_content", sendContent}
};
await backendRepository.AddOneByCustomTable(insertNotify, "background_service_message_notification_task");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
#endregion
}
else
{
#region 使
Dictionary<string, object> userinfo = new Dictionary<string, object>();
var role = await backendRepository.GetOneAsync<byte>(@$"select layer from role where role_guid = '{post.RoleId}'");
var infoguid = await backendRepository.GetAllAsync<string>($@"select r.full_name from userinfo u
left join role r on u.role_guid = r.role_guid
where r.layer = 0 and u.userinfo_guid != '{post.Id}'");
if(infoguid.Count == 0 && role == 1)
{
apiResult.Code = "9998";
var getrolename = await backendRepository.GetOneAsync<string>("select r.full_name from role r where r.layer = 0");
apiResult.Msg = getrolename + "-僅剩一位<br>故無法儲存";
}
else
{
userinfo = new Dictionary<string, object>()
{
{ "@Full_name", post.Name},
{ "@Email", post.Email},
{ "@Role_guid", post.RoleId},
{ "@Phone", post.Phone},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
};
await backendRepository.UpdateOneByCustomTable(userinfo, "userinfo", $"userinfo_guid='{post.Id}'");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
#endregion
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 取得單一使用者
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<SimpleUser>> GetOneUser(string guid)
{
ApiResult<SimpleUser> apiResult = new ApiResult<SimpleUser>();
SimpleUser simpleUser = null;
try
{
simpleUser = await backendRepository.GetOneAsync<SimpleUser>("userinfo", $"userinfo_guid='{guid}'");
if (simpleUser == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該使用者。";
return apiResult;
}
apiResult.Code = "0000";
apiResult.Data = simpleUser;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 軟刪除單一使用者
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> DeleteOneUser(string guid)
{
ApiResult<string> apiResult = new ApiResult<string>();
SimpleUser simpleUser = null;
try
{
simpleUser = await backendRepository.GetOneAsync<SimpleUser>("userinfo", $"userinfo_guid='{guid}'");
if (simpleUser == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該使用者。";
return apiResult;
}
await backendRepository.DeleteOne(guid, "userinfo", "userinfo_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 新增 / 修改 角色
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> SaveRole(PostRole post)
{
ApiResult<string> apiResult = new ApiResult<string>();
RoleManagerList roleManager = null;
try
{
roleManager = await backendRepository.GetOneAsync<RoleManagerList>("role", $"role_guid='{post.Id.ToString()}'");
if (roleManager == null)
{
if (post.Id != "0")
{
apiResult.Code = "9994";
apiResult.Msg = "查無該角色";
return apiResult;
}
#region
//產生一組GUID
var guid = Guid.NewGuid(); //角色GUID
Dictionary<string, object> role = new Dictionary<string, object>();
role = new Dictionary<string, object>()
{
{ "@role_guid", guid},
{ "@Full_name", post.Name},
{ "@created_by", myUserInfo.Userinfo_guid}
};
await backendRepository.AddOneByCustomTable(role, "role");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
#endregion
}
else
{
#region
Dictionary<string, object> role = new Dictionary<string, object>();
role = new Dictionary<string, object>()
{
{ "@Full_name", post.Name},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
};
await backendRepository.UpdateOneByCustomTable(role, "role", $"role_guid='{post.Id}'");
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
#endregion
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 取得單一角色
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<SimpleRole>> GetOneRole(string guid)
{
ApiResult<SimpleRole> apiResult = new ApiResult<SimpleRole>();
SimpleRole simpleRole = null;
try
{
simpleRole = await backendRepository.GetOneAsync<SimpleRole>("role", $"role_guid='{guid}'");
if (simpleRole == null)
{
apiResult.Code = "9994";
apiResult.Msg = "查無該角色";
return apiResult;
}
apiResult.Code = "0000";
apiResult.Data = simpleRole;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 軟刪除單一角色
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> DeleteOneRole(string guid)
{
ApiResult<string> apiResult = new ApiResult<string>();
SimpleRole simpleRole = null;
try
{
simpleRole = await backendRepository.GetOneAsync<SimpleRole>("role", $"role_guid='{guid}'");
if (simpleRole == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該角色";
return apiResult;
}
//檢查是否有使用者為該角色
var sWhere = $@"deleted = 0 AND role_guid = @Guid";
var userInfos = await backendRepository.GetAllAsync<UserInfo>("userinfo", sWhere, new { Guid = guid });
if (userInfos.Count > 0)
{
apiResult.Code = "9997";
apiResult.Msg = "帳號管理中尚有帳號正在使用該角色,故無法刪除";
return apiResult;
}
await backendRepository.DeleteOne(guid, "role", "role_guid");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "Guid=" + guid);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 角色權限管理列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<RoleAuthList>>> RoleAuthList(PostRoleAuthFilter post)
{
ApiResult<List<RoleAuthList>> apiResult = new ApiResult<List<RoleAuthList>>();
List<RoleAuthList> roleAuthList = new List<RoleAuthList>();
try
{
var sqlString = @$"SELECT A.role_guid, A.AuthCode, B.full_name AS 'Role_full_name', C.AuthType, C.MainName, C.SubName, D.full_name AS 'Building_full_name', A.created_at
FROM role_auth A
LEFT JOIN role B ON A.role_guid=B.role_guid AND B.deleted=0
INNER JOIN auth_page C ON A.AuthCode=C.AuthCode
LEFT JOIN building D ON C.building_guid=D.building_guid AND D.deleted=0
WHERE A.role_guid='{post.SelectedRoleId}'
ORDER BY A.created_at DESC";
roleAuthList = await backendRepository.GetAllAsync<RoleAuthList>(sqlString);
apiResult.Code = "0000";
apiResult.Data = roleAuthList;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 取得此角色未選擇的權限
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
public async Task<ApiResult<List<AuthPage>>> GetRoleNotAuthPageList(PostRoleAuthFilter post)
{
ApiResult<List<AuthPage>> apiResult = new ApiResult<List<AuthPage>>();
List<AuthPage> authPage = new List<AuthPage>();
try
{
if (!string.IsNullOrEmpty(post.SelectedRoleId))
{
var buildingGuid = "";
if (post.SelectedBuild != "0")
{
buildingGuid = $" AND ap.building_guid = '{post.SelectedBuild}'";
}
var sqlString = @$" SELECT ap.AuthCode, ap.MainName, ap.SubName FROM auth_page ap
WHERE ap.AuthType='{post.SelectedAuthType}'
{buildingGuid}
AND ap.AuthCode NOT IN (
SELECT ra.AuthCode FROM role_auth ra
LEFT JOIN auth_page ap ON ra.AuthCode = ap.AuthCode
WHERE ra.role_guid = '{post.SelectedRoleId}'
{buildingGuid}
AND ap.AuthType='{post.SelectedAuthType}'
)";
authPage = await backendRepository.GetAllAsync<AuthPage>(sqlString);
}
apiResult.Code = "0000";
apiResult.Data = authPage;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 新增 權限
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> SaveRoleAuth(PostSaveRoleAuth post)
{
ApiResult<string> apiResult = new ApiResult<string>();
RoleManagerList roleManager = null;
try
{
roleManager = await backendRepository.GetOneAsync<RoleManagerList>("role", $"role_guid='{post.SelectedRoleId}'");
if (roleManager == null)
{
apiResult.Code = "9994";
apiResult.Msg = "查無該角色";
return apiResult;
}
else
{
if(post.SaveCheckAuth.Count > 0)
{
foreach (var item in post.SaveCheckAuth)
{
#region
Dictionary<string, object> roleAuth = new Dictionary<string, object>();
roleAuth = new Dictionary<string, object>()
{
{ "@role_guid", post.SelectedRoleId},
{ "@AuthCode", item},
{ "@created_by", myUserInfo.Userinfo_guid}
};
await backendRepository.AddOneByCustomTable(roleAuth, "role_auth");
#endregion
}
}
apiResult.Code = "0000";
apiResult.Msg = "儲存成功";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 刪除 權限
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> DeleteOneRoleAuth(PostDeleteRoleAuth post)
{
ApiResult<string> apiResult = new ApiResult<string>();
RoleManagerList roleManager = null;
try
{
roleManager = await backendRepository.GetOneAsync<RoleManagerList>("role", $"role_guid='{post.RoleId}'");
if (roleManager == null)
{
apiResult.Code = "9994";
apiResult.Msg = "查無該角色";
return apiResult;
}
await backendRepository.PurgeOneByGuidWithCustomDBNameAndTable("role_auth", $"role_guid='{post.RoleId}' AND AuthCode='{post.AuthCode}'");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
}
}

View File

@ -0,0 +1,226 @@
using Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Controllers
{
public class VariableController : MybaseController<VariableController>
{
private readonly IBackendRepository backendRepository;
public VariableController(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// SystemType列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<KeyValue>>> SystemTypeList()
{
ApiResult<List<KeyValue>> apiResult = new ApiResult<List<KeyValue>>();
try
{
var sqlString = @$"SELECT DISTINCT system_type as Name, system_type as Value FROM variable v WHERE v.deleted = 0 ORDER BY v.system_type";
var KeyValue = await backendRepository.GetAllAsync<KeyValue>(sqlString);
apiResult.Code = "0000";
apiResult.Data = KeyValue;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 系統變數資料列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<List<VariableInfo>>> VariableInfoList(PostVariableInfoFilter post)
{
ApiResult<List<VariableInfo>> apiResult = new ApiResult<List<VariableInfo>>();
try
{
var sWhere = "deleted = 0";
if (!string.IsNullOrEmpty(post.SelectedSystemType))
{
sWhere += " AND system_type = @SystemType";
}
var variableInfos = await backendRepository.GetAllAsync<VariableInfo>("variable", sWhere, new { SystemType = post.SelectedSystemType }, "system_type, system_priority");
apiResult.Code = "0000";
apiResult.Data = variableInfos;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 系統變數資料列表
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<VariableInfo>> GetOneVariable(int id)
{
ApiResult<VariableInfo> apiResult = new ApiResult<VariableInfo>();
try
{
string sWhere = @$"deleted = 0 AND id = @Id";
object param = new { Id = id };
var variableInfo = await backendRepository.GetOneAsync<VariableInfo>("variable", sWhere, param);
apiResult.Code = "0000";
apiResult.Data = variableInfo;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 新增 / 修改 系統變數資料
/// </summary>
/// <param name="post"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> SaveVariable(VariableInfo post)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = 0 AND id = @Id";
object param = new { Id = post.id };
var variableInfo = await backendRepository.GetOneAsync<VariableInfo>("variable", sWhere, param);
if (variableInfo == null)
{
//新增
Dictionary<string, object> variableInfoDic = new Dictionary<string, object>()
{
{ "@system_type", post.System_type},
{ "@system_key", post.System_key},
{ "@system_value", post.system_value},
{ "@system_remark", post.system_remark},
{ "@system_priority", post.system_priority},
{ "@system_parent_id", post.system_parent_id},
{ "@created_by", myUserInfo.Userinfo_guid},
};
await backendRepository.AddOneByCustomTable(variableInfoDic, "variable");
apiResult.Code = "0000";
apiResult.Msg = "新增成功";
}
else
{
Dictionary<string, object> variableInfoDic = new Dictionary<string, object>()
{
{ "@system_type", post.System_type},
{ "@system_key", post.System_key},
{ "@system_value", post.system_value},
{ "@system_remark", post.system_remark},
{ "@system_priority", post.system_priority},
{ "@system_parent_id", post.system_parent_id},
{ "@updated_by", myUserInfo.Userinfo_guid},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
await backendRepository.UpdateOneByCustomTable(variableInfoDic, "variable", "id=" + variableInfo.id);
apiResult.Code = "0000";
apiResult.Msg = "修改成功";
}
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
/// <summary>
/// 刪除單一系統變數
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult<string>> DeleteOneVariable(int id)
{
ApiResult<string> apiResult = new ApiResult<string>();
try
{
string sWhere = @$"deleted = 0 AND id = @Id";
object param = new { Id = id };
var variableInfo = await backendRepository.GetOneAsync<VariableInfo>("variable", sWhere, param);
if (variableInfo == null)
{
apiResult.Code = "9998";
apiResult.Msg = "查無該系統變數";
return apiResult;
}
await backendRepository.DeleteOne(id.ToString(), "variable", "id");
apiResult.Code = "0000";
apiResult.Msg = "刪除成功";
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "id=" + id.ToString());
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
}
}

90
Backend/Jwt/JwtHelpers.cs Normal file
View File

@ -0,0 +1,90 @@
using Backend.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace Backend.Jwt
{
public interface IJwtHelpers
{
TnToken GenerateToken(JwtLogin login);
}
public class JwtHelpers: IJwtHelpers
{
private readonly IConfiguration _configuration;
public JwtHelpers(IConfiguration configuration)
{
_configuration = configuration;
}
public TnToken GenerateToken(JwtLogin login)
{
var issuer = _configuration.GetValue<string>("JwtSettings:Issuer");
var signKey = _configuration.GetValue<string>("JwtSettings:SignKey");
var lifeseconds = _configuration.GetValue<int>("JwtSettings:JwtLifeSeconds");
// 設定要加入到 JWT Token 中的聲明資訊(Claims)
var claims = new List<Claim>();
// 在 RFC 7519 規格中(Section#4),總共定義了 7 個預設的 Claims我們應該只用的到兩種
claims.Add(new Claim(JwtRegisteredClaimNames.Iss, issuer));
//claims.Add(new Claim(JwtRegisteredClaimNames.NameId, login.CustomerNo.ToString()));
//claims.Add(new Claim(JwtRegisteredClaimNames.Sub, login.Username)); // User.Identity.Name
//claims.Add(new Claim(JwtRegisteredClaimNames.Aud, "The Audience"));
//claims.Add(new Claim(JwtRegisteredClaimNames.Exp, DateTimeOffset.UtcNow.AddSeconds(expireSeconds).ToUnixTimeSeconds().ToString()));
//claims.Add(new Claim(JwtRegisteredClaimNames.Nbf, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString())); // 必須為數字
//claims.Add(new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString())); // 必須為數字
//claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())); // JWT ID
// 網路上常看到的這個 NameId 設定是多餘的
//claims.Add(new Claim(JwtRegisteredClaimNames.NameId, userName));
// 這個 Claim 也以直接被 JwtRegisteredClaimNames.Sub 取代,所以也是多餘的
//claims.Add(new Claim(ClaimTypes.Name, userName));
// 你可以自行擴充 "roles" 加入登入者該有的角色
//claims.Add(new Claim("roles", "Users"));
//claims.Add(new Claim("groupid", login.AreaCode));
claims.Add(new Claim("userinfo_guid", login.userinfo_guid));
claims.Add(new Claim("account", login.account));
claims.Add(new Claim("full_name", login.full_name));
claims.Add(new Claim("email", login.email));
var userClaimsIdentity = new ClaimsIdentity(claims);
// 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey));
// HmacSha256 有要求必須要大於 128 bits所以 key 不能太短,至少要 16 字元以上
// https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
var now = DateTime.Now;
var expires = DateTime.Now.AddSeconds(lifeseconds);
// 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
var tokenHandler = new JwtSecurityTokenHandler();
var jst = new JwtSecurityToken(
issuer: issuer,//Token釋出者
//audience: _options.Value.Audience,//Token接受者
claims: claims,//攜帶的負載
notBefore: now,//當前時間token生成時間
expires: expires,//過期時間
signingCredentials: signingCredentials
);
var serializeToken = tokenHandler.WriteToken(jst);
var data = new TnToken();
data.token = serializeToken;
data.type = "bearer";
data.expires= lifeseconds;
return data;
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Jwt
{
public class JwtSettings
{
/// <summary>
/// Token釋出者
/// </summary>
public string Issuer { get; set; }
/// <summary>
/// 祕鑰
/// </summary>
public string SignKey { get; set; }
}
}

23
Backend/Jwt/TnToken.cs Normal file
View File

@ -0,0 +1,23 @@
using System;
namespace Backend.Jwt
{
/// <summary>
/// 存放Token 跟過期時間的類
/// </summary>
public class TnToken
{
/// <summary>
/// token
/// </summary>
public string token { get; set; }
/// <summary>
/// type
/// </summary>
public string type { get; set; }
/// <summary>
/// 過期時間
/// </summary>
public int expires { get; set; }
}
}

22
Backend/Models/Archive.cs Normal file
View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class ArchiveElectricMeter
{
public string Device_number { get; set; }
public string Point { get; set; }
public string Start_timestamp { get; set; }
public string End_timestamp { get; set; }
public int Count_rawdata { get; set; }
public double Min_rawdata { get; set; }
public double Max_rawdata { get; set; }
public double Avg_rawdata { get; set; }
public double Sum_rawdata { get; set; }
public byte Is_complete { get; set; }
public double Repeat_times { get; set; }
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public enum MessageNotificationTaskType : byte
{
email = 0,
sms = 1,
line_notify = 2,
}
public class BackgroundServiceMessageNotificationTask
{
private string complete_at;
private string created_at;
private string updated_at;
public int Id { get; set; }
public byte Task_type { get; set; }
public string Recipient_name { get; set; }
public string Recipient_phone { get; set; }
public string Recipient_email { get; set; }
public string Line_token { get; set; }
public string Email_subject { get; set; }
public string Message_content { get; set; }
public int Repeat_times { get; set; }
public byte Is_complete { get; set; }
public string Complete_at { get { return Convert.ToDateTime(complete_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { complete_at = value; } }
public string Created_at { get { return Convert.ToDateTime(created_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { created_at = value; } }
public string Updated_at { get { return Convert.ToDateTime(updated_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { updated_at = value; } }
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public enum ExecutionTypeEnum : byte
{
Min = 0, //分
Hour = 1, //時
Day = 2, //天
Week = 3, //週
Month = 4 //月
}
public class BackgroundServicePlan
{
private string start_time;
private string end_time;
private string last_create_time;
public int Id { get; set; }
public string Plane_name { get; set; }
public string building_guid { get; set; }
public string Target_table { get; set; }
public int Execution_time { get; set; }
public byte Execution_type { get; set; }
public string Start_time { get { return Convert.ToDateTime(start_time).ToString("yyyy-MM-dd HH:mm:ss"); } set { start_time = value; } }
public string End_time { get { return Convert.ToDateTime(end_time).ToString("yyyy-MM-dd HH:mm:ss"); } set { end_time = value; } }
public string Last_create_time { get { return Convert.ToDateTime(last_create_time).ToString("yyyy-MM-dd HH:mm:ss"); } set { last_create_time = value; } }
public int Repeat_times { get; set; }
public byte status { get; set; }
}
public class PlanTable: BackgroundServicePlan
{
public string building { get; set; }
public string execution { get; set; }
public string time { get; set; }
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public enum BackgroundServiceTaskType : byte
{
raw_data_archive = 0, //資料歸檔
data_delivery = 1, //資料派送
}
public class BackgroundServiceTask
{
private string complete_at;
private string created_at;
private string updated_at;
public int Id { get; set; }
public byte Task_type { get; set; }
public string Target_ip { get; set; }
public string Target_table { get; set; }
public string Mode { get; set; }
public string Target_data { get; set; }
public string Target_files { get; set; }
public int Repeat_times { get; set; }
public byte Is_complete { get; set; }
public string Complete_at { get { return Convert.ToDateTime(complete_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { complete_at = value; } }
public string Created_at { get { return Convert.ToDateTime(created_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { created_at = value; } }
public string Updated_at { get { return Convert.ToDateTime(updated_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { updated_at = value; } }
}
public class FileInfo
{
public string Folder { get; set; }
public string OriginalFileName { get; set; }
public string FileName { get; set; }
public string File { get; set; }
}
}

View File

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class BuildMenu : Actor
{
public string building_guid { get; set; }
public string main_system_guid { get; set; }
public string sub_system_guid { get; set; }
public byte drawing { get; set; }
public byte icon_click { get; set; }
public string icon_click_url { get; set; }
public int icon_click_url_width { get; set; }
public int icon_click_url_height { get; set; }
public string system_url { get; set; }
public string riser_diagram_url { get; set; }
public byte planimetric_click { get; set; }
public string planimetric_floor_guid { get; set; }
}
public class BuildMenuAddSub: BuildMenu
{
public string sub_system_guid_name { get; set; }
}
public class SubListIn
{
public string main { get; set; }
public string build { get; set; }
}
public class BuildMenuTablePost
{
public string build { get; set; }
public List<string> MainList { get; set; }
}
public class BuildMenuTable: BuildMenu
{
public string main_system_guid_name { get; set; }
public string sub_system_guid_name { get; set; }
public string drawing_name { get; set; }
public string icon_click_name { get; set; }
public string planimetric_click_name { get; set; }
public string floor_guid_name { get; set; }
}
public class MenuIn : SubListIn
{
public string sub { get; set; }
}
public class BuildMenuFloor : Actor
{
public string sub_system_floor_guid { get; set; }
public byte deleted { get; set; }
public byte status { get; set; }
public string building_guid { get; set; }
public string main_system_guid { get; set; }
public string sub_system_guid { get; set; }
public string floor_guid { get; set; }
}
public class BuildMenuFloorTable : BuildMenuFloor
{
public string main_system_guid_name { get; set; }
public string sub_system_guid_name { get; set; }
public string floor_guid_name { get; set; }
}
public class MenuInfloor: MenuIn
{
public List<string> floorlist { get; set; }
}
}

View File

@ -0,0 +1,57 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class BuildInfo : Actor
{
public int Priority { get; set; }
public string Building_guid { get; set; } //區域GUID
public string Full_name { get; set; } //區域名稱
public string Ip_address { get; set; } //監控主機 IP
public string Ip_port { get; set; } //監控主機 IP port
public string Ip_address_port { get { return Ip_address + ":" + Ip_port; } }
public byte FloorNum { get; set; } //樓層數量
//public string Created_at { get; set; } //建立時間
}
public class BuildFloor : Actor
{
public string Floor_guid { get; set; } //樓層GUID
public string Building_guid { get; set; } //區域GUID
public string Full_name { get; set; } //建築名稱
public string InitMapName { get; set; } //使用者命名平面圖檔檔名
public string MapUrl { get; set; } //使用者命名平面圖檔檔名
public string Floor_map_name { get; set; } //平面圖檔名
public IFormFile MapFile { get; set; } //平面圖檔
public int Priority { get; set; }
}
public class SelectedBuildFloor
{
public string SelectedGuid { get; set; } //區域GUID
}
public class PostBuildInfoPriority
{
public List<BuildInfoPriority> BuildInfoPriorities { get; set; }
}
public class BuildInfoPriority
{
public string Building_guid { get; set; } //區域GUID
public int Priority { get; set; }
}
public class PostFloorPriority
{
public List<FloorPriority> FloorPriorities { get; set; }
}
public class FloorPriority
{
public string Floor_guid { get; set; } //樓層GUID
public int Priority { get; set; }
}
}

View File

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class BuildingMenuRawData
{
public string Building_guid { get; set; }
public string bFull_name { get; set; }
public int bPriority { get; set; }
public string Main_system_guid { get; set; }
public string mFull_name { get; set; }
public int mPriority { get; set; }
public string Sub_system_guid { get; set; }
public string sFull_name { get; set; }
public int sPriority { get; set; }
}
public class BuildingCollapse : Actor
{
public string Building_guid { get; set; }
public string Full_name { get; set; }
public string Ip_address { get; set; }
public int Priority { get; set; }
public List<Main_system> Main_systems { get; set; }
}
public class Main_system
{
public string Main_system_guid { get; set; }
public string Full_name { get; set; }
public int Priority { get; set; }
public string Code { get; set; }
public List<Sub_system> Sub_systems { get; set; }
}
public class Sub_system
{
public string Sub_system_guid { get; set; }
public string Full_name { get; set; }
public int Priority { get; set; }
public byte Drawing { get; set; }
public byte Icon_click { get; set; }
public string Icon_click_url { get; set; }
public string System_url { get; set; }
public List<Floor> Floors { get; set; }
}
public class Floor
{
public string Floor_guid { get; set; }
public string Full_name { get; set; }
public string InitMapName { get; set; }
public string Floor_map_name { get; set; } //平面圖檔名
public int Priority { get; set; }
}
public class SubSystemFloorRawData
{
public string Sub_system_floor_guid { get; set; }
public string Building_guid { get; set; }
public string Main_system_guid { get; set; }
public string Sub_system_guid { get; set; }
public string Floor_guid { get; set; }
public string fFull_name { get; set; }
public string InitMapName { get; set; }
public string Floor_map_name { get; set; }
public string fPriority { get; set; }
public int Priority { get; set; }
}
}

266
Backend/Models/Device.cs Normal file
View File

@ -0,0 +1,266 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class PostDeviceFilter
{
public string Building_guid { get; set; }
public string Main_system_guid { get; set; }
public string Sub_system_guid { get; set; }
public string Floor_guid { get; set; }
}
public class PostDeviceInfoAdd
{
public string Building_guid { get; set; }
public string Main_system_guid { get; set; }
public string Sub_system_guid { get; set; }
public string Floor_guid { get; set; }
public List<SelcectedDeviceAdd> SelectedDevices { get; set; }
public IFormFile SelectedDevicesFile { get; set; }
}
public class SelcectedDeviceAdd
{
public string Device_number { get; set; }
public string Device_system_category_layer3 { get; set; }
public string Device_disasters { get; set; }
}
public class PostDeviceInfoEdit
{
public string Device_guid { get; set; }
public string Full_name { get; set; }
public string Device_coordinate_x { get; set; }
public string Device_coordinate_y { get; set; }
public List<string> Device_disasters { get; set; }
public string Device_ip { get; set; }
public string Device_port { get; set; }
}
public class PostDeviceCoordinate
{
public string Device_guid { get; set; }
public string Device_node_guid { get; set; }
public string Coordinate { get; set; }
}
public class Device : Actor
{
public string Device_guid { get; set; }
public byte Deleted { get; set; }
public byte Status { get; set; }
public string Building_guid { get; set; }
public string Building_full_name { get; set; }
public string Main_system_guid { get; set; }
public string Main_system_full_name { get; set; }
public string Sub_system_guid { get; set; }
public string Sub_system_full_name { get; set; }
public string Floor_guid { get; set; }
public string Floor_full_name { get; set; }
public string Device_coordinate { get; set; }
public string Device_full_name { get; set; }
public string Device_number { get; set; } //設備編號
public string Device_model { get; set; } //設備型號
public string Device_disaster_type_text { get; set; }
public string Device_system_category_layer3 { get; set; }
public string Device_image { get; set; }
public string Device_image_url { get; set; }
public string Device_close_color { get; set; }
public string Device_normal_color { get; set; }
public string Device_error_color { get; set; }
public string Device_flashing { get; set; }
public string Device_ip { get; set; }
public string Device_port { get; set; }
public List<DeviceDisaster> Device_disasters { get; set; } //防災類型
public List<DeviceNode> Device_nodes { get; set; } //設備子節點
}
public class DeviceDisaster
{
public int Id { get; set; }
public string Device_system_type { get; set; }
public string Device_system_value { get; set; }
}
public class PostDeviceNode
{
public string Device_node_guid { get; set; }
public string Device_guid { get; set; }
public string Full_name { get; set; }
public string Device_node_coordinate_x { get; set; }
public string Device_node_coordinate_y { get; set; }
}
public class DeviceNode : Actor
{
public string Device_node_guid { get; set; }
public string Device_guid { get; set; }
public string Device_node_full_name { get; set; }
public string Device_node_coordinate { get; set; }
public int Priority { get; set; }
}
public class PostDeviceKind
{
public string Device_kind_guid { get; set; }
public string Device_building_tag { get; set; }
public string Device_system_tag { get; set; }
public string Device_floor_tag { get; set; }
public string Device_name_tag { get; set; }
public string Device_image { get; set; }
public string InitDeviceName { get; set; }
public IFormFile Device_image_file { get; set; } //設備種類圖檔
public string Device_normal_text { get; set; }
public string Device_normal_point_guid { get; set; }
public string Device_normal_point_col { get; set; }
public string Device_normal_point_value { get; set; }
public string Device_normal_color { get; set; }
public byte Device_normal_flashing { get; set; }
public string Device_close_text { get; set; }
public string Device_close_point_guid { get; set; }
public string Device_close_point_col { get; set; }
public string Device_close_point_value { get; set; }
public string Device_close_color { get; set; }
public byte Device_close_flashing { get; set; }
public string Device_error_text { get; set; }
public string Device_error_point_guid { get; set; }
public string Device_error_point_col { get; set; }
public string Device_error_point_value { get; set; }
public string Device_error_color { get; set; }
public byte Device_error_flashing { get; set; }
public byte Device_error_independent { get; set; }
}
public class DeviceKind
{
public string Device_kind_guid { get; set; }
public string Device_building_tag { get; set; }
public string Device_system_tag { get; set; }
public string Device_floor_tag { get; set; }
public string Device_name_tag { get; set; }
public string Device_image { get; set; }
public string Device_normal_text { get; set; }
public string Device_normal_point_guid { get; set; }
public string Device_normal_point_name { get; set; }
public string Device_normal_point_col { get; set; }
public string Device_normal_point_value { get; set; }
public string Device_normal_color { get; set; }
public byte Device_normal_flashing { get; set; }
public string Device_close_text { get; set; }
public string Device_close_point_guid { get; set; }
public string Device_close_point_name { get; set; }
public string Device_close_point_col { get; set; }
public string Device_close_point_value { get; set; }
public string Device_close_color { get; set; }
public byte Device_close_flashing { get; set; }
public string Device_error_text { get; set; }
public string Device_error_point_guid { get; set; }
public string Device_error_point_name { get; set; }
public string Device_error_point_col { get; set; }
public string Device_error_point_value { get; set; }
public string Device_error_color { get; set; }
public byte Device_error_flashing { get; set; }
public byte Device_error_independent { get; set; }
}
public class PointName
{
public string Device_normal_point_name { get; set; }
public string Device_close_point_name { get; set; }
public string Device_error_point_name { get; set; }
}
public class DeviceImportCheckTempRawData
{
public string Device_building_tag { get; set; }
public string Device_system_tag { get; set; }
public string Device_floor_tag { get; set; }
public string Device_name_tag { get; set; }
public string Device_serial_tag { get; set; }
public string Device_number { get; set; }
public string Device_system_category_layer3 { get; set; }
}
public class DeviceImportCheckTempFilter
{
public string Device_building_tag { get; set; }
public List<ImportTempDeviceSystemTag> Device_system_tags { get; set; }
}
public class ImportTempDeviceSystemTag
{
public string Device_system_tag { get; set; }
public List<ImportTempDeviceFloorTag> Device_floor_tags { get; set; }
}
public class ImportTempDeviceFloorTag
{
public string Device_floor_tag { get; set; }
public List<string> Device_name_tags { get; set; }
}
public class DeviceImportCheckTemp : Actor
{
public string Device_building_tag { get; set; }
public string Device_system_tag { get; set; }
public string Device_floor_tag { get; set; }
public string Device_name_tag { get; set; }
public string Device_serial_tag { get; set; }
public string Device_number { get; set; }
public string Device_disasters { get; set; }
public string Device_disaster_type_text { get; set; }
public string Device_system_category_layer3 { get; set; }
}
public class DeviceMaster : Actor
{
public string Device_master_guid { get; set; }
public string Device_building_tag { get; set; }
public string Device_name_tag { get; set; }
public string Device_master_number { get; set; }
public string Device_master_full_name { get; set; }
public string Device_master_icon { get; set; }
}
public class PostDeviceMaster
{
public string Device_master_guid { get; set; }
public string Device_building_tag { get; set; }
public string Device_name_tag { get; set; }
public string Device_master_number { get; set; }
public string Device_master_full_name { get; set; }
public IFormFile Device_master_icon_file { get; set; } //設備種類圖檔
}
public class DeviceGroup
{
public int id { get; set; }
public string device_disaster { get; set; }
public string device_building_guid { get; set; }
public string device_floor_guid { get; set; }
public string device_system_category_layer2 { get; set; }
public string device_system_category_layer3 { get; set; }
public int device_amount { get; set; }
}
/// <summary>
/// 由API方式修改設備名稱
/// </summary>
public class ChangeName
{
public string TagName { get; set; }
public string ChangeN { get; set; }
public byte ChooseTable { get; set; }
}
public class DeviceNumberPoint
{
public string DeviceNumber { get; set; }
public string Point { get; set; }
public string FullDeviceNumberPoint { get; set; }
}
}

View File

@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class DeviceImport
{
private string created_at;
public int Id { get; set; }
public string Device_number { get; set; }
public string Device_result { get; set; }
public string Created_at { get { return Convert.ToDateTime(created_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { created_at = value; } } //創建時間
}
public class DeviceCheckFilterRawData
{
public string Device_building_tag { get; set; }
public string Device_system_tag { get; set; }
public string Device_system_category_layer3 { get; set; }
}
public class Device_import_ckeck_temp_replace
{
public string Device_building_tag { get; set; }
public string Device_system_tag { get; set; }
public string Device_floor_tag { get; set; }
public string Device_name_tag { get; set; }
public string Device_serial_tag { get; set; }
public string Device_number { get; set; }
public string Device_system_category_layer3 { get; set; }
public string Device_disaster { get; set; }
public string Device_guid { get; set; }
}
public class Device_replace_dict
{
public Dictionary<string, object> Device_replace { get; set; }
public List<Dictionary<string, object>> Device_disaster_dicts { get; set; }
}
public class DeviceCheckFilter
{
public string Building_tag { get; set; }
public int Building_amount { get; set; }
public List<DeviceCheckSystemTag> System_tags { get; set; }
}
public class DeviceCheckSystemTag
{
public string System_tag { get; set; }
public List<string> System_categories { get; set; }
}
public class PostDeviceCheckFilter
{
public string Building_tag { get; set; }
public string System_tag { get; set; }
public string System_category { get; set; }
public string Abnormal { get; set; }
}
public class DeviceCheck
{
public int DeviceCheckAmount { get; set; }
public List<DeviceCheckTable> DeviceCheckTableList { get; set; }
}
public class DeviceCheckTable
{
public string Check_temp_device_number { get; set; } //check temp 資料表的 device_number
public string Check_temp_device_system_category_layer3 { get; set; } //check temp 資料表的 system_category_layer3 value
public string Check_temp_device_system_category_layer3_key { get; set; } //check temp 資料表的 system_category_layer3 key
public string Check_temp_disaster_key { get; set; } //check temp 資料表的 disaster
public string Device_number { get; set; } //device 資料表的 device_number
public string Device_system_category_layer3 { get; set; } //device 資料表的 system_category_layer3 value
public string Device_system_category_layer3_key { get; set; } //device 資料表的 system_category_layer3 key
public string Device_disaster_type_text { get; set; } //device_disaster 資料表的 disaster
public string Device_coordinate { get; set; } //device 資料表的 device_coordinate
public byte Compare_device_number { get; set; } //比對2資料表的device_number
public byte Compare_system_category_layer3 { get; set; } //比對2資料表的system_category_layer3
public byte Compare_device_disaster { get; set; } //device 資料表的 device_disaster
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class EmergencyContact
{
public string emergency_member_guid { get; set; }
public int grouping { get; set; }
public string full_name { get; set; }
public int department { get; set; }
public string phone { get; set; }
public string lineid { get; set; }
public string email { get; set; }
}
public class EmergencyContactTable: EmergencyContact
{
public string groupingName { get; set; }
public string departmentName { get; set; }
}
public class export
{
public List<int> groupidlist { get; set; }
public string disaster { get; set; }
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class EmergencyGrouping
{
}
public class SaveGrouping
{
public int id { get; set; }
public int priority { get; set; }
public string name { get; set; }
public string disaster { get; set; }
public byte verify { get; set; }
}
public class KeyValueID: KeyValue
{
public int id { get; set; }
}
public class Emergency_member
{
public string emergency_member_guid { get; set; }
public int grouping { get; set; }
public string full_name { get; set; }
public int department { get; set; }
public string phone { get; set; }
public string lineid { get; set; }
public string email { get; set; }
}
public class Emergency_member_table : Emergency_member
{
public string grouping_name { get; set; }
public string department_name { get; set; }
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class EmergencyRecord
{
}
public class EmergencyRecordEventPost
{
public int selectaDisaster { get; set; }
public string selectaBuild { get; set; }
public int selectaType { get; set; }
public string dateranger { get; set; }
}
public class EmergencyRecordEvent: Actor
{
public string emergency_event_guid { get; set; }
public int disaster { get; set; }
public string device_guid { get; set; }
public string building_guid { get; set; }
public byte type { get; set; }
}
public class EmergencyRecordEventTable: EmergencyRecordEvent
{
public string disaster_name { get; set; }
public string device_name { get; set; }
public string building_name { get; set; }
}
public class EmergencyRecordItem: Actor
{
public string emergency_item_guid { get; set; }
public string big_setting { get; set; }
public string step_setting { get; set; }
public byte finished { get; set; }
public string reason { get; set; }
}
}

View File

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class EmergencySetting
{
public string emergency_guid { get; set; }
public int priority { get; set; }
public int big_setting { get; set; }
public string full_name { get; set; }
public string set_doing { get; set; }
public string url_text { get; set; }
public string url_link { get; set; }
public byte not_answer { get; set; }
}
public class EmergencySettingTable: EmergencySetting
{
public string big_setting_name { get; set; }
}
public class EmergencyitemWithguid: EmergencySettingTable
{
public string emergency_item_guid { get; set; }
}
public class Emergencyitempost
{
public string emergency_guid { get; set; }
public string big_setting { get; set; }
public string step_setting { get; set; }
public string event_guid { get; set; }
public byte make_item { get; set; }
}
public class Eventpost
{
public int disaster { get; set; }
public string build { get; set; }
public byte type { get; set; }
}
public class Itempost
{
public string eventguid { get; set; }
public byte choose { get; set; }
public string reason { get; set; }
}
public class Eventitem
{
private string updated_at;
public string big_setting { get; set; }
public string step_setting { get; set; }
public byte finished { get; set; }
public string Updated_at { get { return Convert.ToDateTime(updated_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { updated_at = value; } }
public string reason { get; set; }
}
}

View File

@ -0,0 +1,11 @@
using System;
namespace Backend.Models
{
public class ErrorViewModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class ForgotPasswordViewModel
{
[Required(ErrorMessage = "信箱為必填欄位")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class LoginViewModel
{
[Required(ErrorMessage = "帳號為必填欄位")]
public string Account { get; set; }
[Required(ErrorMessage = "密碼為必填欄位")]
[DataType(DataType.Password)]
public string Password { get; set; }
}
}

87
Backend/Models/Mybase.cs Normal file
View File

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
/// <summary>
/// 基礎BaseModel
/// </summary>
public class Mybase
{
public string Guid { get; set; } //編號
}
public class Actor
{
private string created_at;
private string updated_at;
public string Created_by { get; set; } //創建者
public string Created_at { get { return Convert.ToDateTime(created_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { created_at = value; } } //創建時間
public string Updated_by { get; set; } //修改者
public string Updated_at { get { return Convert.ToDateTime(updated_at).ToString("yyyy-MM-dd HH:mm:ss"); } set { updated_at = value; } } //修改時間
}
/// <summary>
/// 當前登入的使用者基本資訊
/// </summary>
public class MyUserInfo
{
public string Userinfo_guid { get; set; } //編號
public byte Status { get; set; } //狀態
public string Full_name { get; set; } //姓名
public string Phone { get; set; } //手機
public string Tel { get; set; } //市話
public string Email { get; set; }
public string role_guid { get; set; }
public byte Layer { get; set; }
public List<string> ShowView { get; set; }
}
/// <summary>
/// 當前登入使用者的公司資訊
/// </summary>
public class MyCompany
{
private string logo;
public int Id { get; set; }
public byte Status { get; set; } //狀態
public string Name { get; set; } //名稱
public string Logo { get; set; }
}
public class Variable
{
public string System_type { get; set; }
public string System_key { get; set; }
public string system_value { get; set; }
}
public class VariableInfo : Variable
{
public int id { get; set; }
public string system_remark { get; set; }
public int system_priority { get; set; }
public int system_parent_id { get; set; }
}
public class PostVariableInfoFilter
{
public string SelectedSystemType { get; set; }
}
public class KeyValue
{
public string Name { get; set; }
public string Value { get; set; }
}
public class CheckBox
{
public int Value { get; set; } //通常放id
public string Name { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class ObixApiConfig
{
public string ApiBase { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models.OperatorLogModel
{
public class OperatorLog
{
public int id { get; set; }
public string controller_name { get; set; }
public string action_name { get; set; }
public string parameter { get; set; }
public string created_by { get; set; }
public string created_at { get; set; }
}
}

63
Backend/Models/Parking.cs Normal file
View File

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public enum VehicleTypeEnum : byte
{
Car = 1, //汽車
MOTO = 2, //機車
}
public class ParkingConfig
{
public string Host { get; set; }
public string Prefix { get; set; }
public string ApiBase { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
}
public class SpaceResponse
{
public string Code { get; set; }
public Payload Payload { get; set; }
}
public class Payload
{
public List<CarType> Car_types { get; set; } //該場地所有車位資訊
public List<Area> Areas { get; set; }
}
public class CarType
{
public int Vehicle_type_id { get; set; } //車種(請參照車種列表)
public int Total { get; set; } //該車種總車位數
public int Remain { get; set; } //該車種剩餘車位數
}
public partial class Area
{
public string Name { get; set; }
public int Vehicle_type_id { get; set; }
public int Total { get; set; }
public int Remain { get; set; }
}
public class EquipmentResponse
{
public string Code { get; set; }
public List<EquipmentPayload> Payload { get; set; }
}
public class EquipmentPayload
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public bool Alive { get; set; }
}
}

View File

@ -0,0 +1,67 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class RescueDevice
{
public string rescue_device_guid { get; set; }
public string rescue_device_id { get; set; }
public string floor_guid { get; set; }
public string floor_name { get; set; }
public string location { get; set; }
}
public class SaveFireExtinguisher
{
public string guid { get; set; }
public string location { get; set; }
}
public class RescueDeviceTableUse
{
public string build { get; set; }
public List<string> floors { get; set; }
public byte kind { get; set; }
}
public class ImportRescueDevice
{
public IFormFile import_file { get; set; }
public byte kind { get; set; }
public string building { get; set; }
}
public class RescueDeviceTable
{
public string rescue_device_guid { get; set; }
public string rescue_device_id { get; set; }
public string building_guid { get; set; }
public string floor_guid { get; set; }
public string floor_name { get; set; }
public string location { get; set; }
}
public class Excel
{
public string build { get; set; }
public byte kind { get; set; }
public string buildname { get; set; }
}
public class NpoiMemoryStream : MemoryStream
{
public NpoiMemoryStream()
{
AllowClose = true;
}
public bool AllowClose { get; set; }
public override void Close()
{
if (AllowClose)
base.Close();
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class SMSConfig
{
public string UserName { get; set; }
public string Password { get; set; }
public string Encoded { get; set; }
public string Api { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class SMTPConfig
{
public string Host { get; set; }
public int Port { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public bool EnableSsl { get; set; }
}
}

243
Backend/Models/Share.cs Normal file
View File

@ -0,0 +1,243 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Backend.Models
{
/// <summary>
/// Encryption Decryption Function - 加解密
/// </summary>
public class EDFunction
{
const string SHA256_KEY = "DOMETAIPEI"; //自訂金鑰
const string DES_KEY = "TAIPEIDO"; //DES_KEY金鑰(8位字元)
const string DES_IV = "TAIPEIDO"; //DES_IV初始化向量字串(8位字元)
const string AES_KEY = "TAIPEIDO"; //AES_KEY金鑰
const string AES_IV = "TAIPEIDO"; //AES_IV初始化向量字串
/// <summary>
/// 單向加密SHA256
/// </summary>
/// <param name="text">加密字串</param>
/// <returns></returns>
public string GetSHA256Encryption(string text)
{
string signRet = string.Empty;
byte[] key_byte = Encoding.Default.GetBytes(SHA256_KEY);
using (HMACSHA256 mac = new HMACSHA256(key_byte))
{
byte[] source = Encoding.Default.GetBytes(text);//將字串轉為Byte[]
byte[] crypto = mac.ComputeHash(source);//進行SHA256加密
signRet = Convert.ToBase64String(crypto);//把加密後的字串從Byte[]轉為字串
}
return signRet;
}
/// <summary>
/// DES加密
/// </summary>
/// <param name="text">待加密資料</param>
/// <returns></returns>
public string DESEncrypt(string text)
{
try
{
byte[] byKey = Encoding.ASCII.GetBytes(DES_KEY); //密鑰
byte[] byIV = Encoding.ASCII.GetBytes(DES_IV); //IV值
byte[] data = Encoding.Unicode.GetBytes(text);
DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();//加密、解密對象
MemoryStream MStream = new MemoryStream();//內存流對象
//用內存流實例化加密流對象
CryptoStream CStream = new CryptoStream(MStream, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);
CStream.Write(data, 0, data.Length);//向加密流中寫入數據
CStream.FlushFinalBlock();//將數據壓入基礎流
byte[] temp = MStream.ToArray();//從內存流中獲取字節序列
CStream.Close();//關閉加密流
MStream.Close();//關閉內存流
return Convert.ToBase64String(temp);//返回加密後的字符串
}
catch
{
return text;
}
}
/// <summary>
/// DES解密
/// </summary>
/// <param name="text">待解密字符串</param>
/// <returns></returns>
public string DESDecrypt(string text)
{
try
{
byte[] byKey = Encoding.ASCII.GetBytes(DES_KEY); //DES密鑰
byte[] byIV = Encoding.ASCII.GetBytes(DES_IV); //IV值
byte[] data = Convert.FromBase64String(text);
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();
MemoryStream MStream = new MemoryStream();
//用內存流實例化解密流對象
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(byKey, byIV), CryptoStreamMode.Write);
CStream.Write(data, 0, data.Length);//向加密流中寫入數據
CStream.FlushFinalBlock();//將數據壓入基礎流
byte[] temp = MStream.ToArray();//從內存流中獲取字節序列
CStream.Close();//關閉加密流
MStream.Close();//關閉內存流
return Encoding.Unicode.GetString(temp);//返回解密後的字符串
}
catch
{
return text;
}
}
/// <summary>
/// AES加密
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public string AESEncrypt(string text)
{
var encrypt = "";
try
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider();
byte[] keyData = sha256.ComputeHash(Encoding.UTF8.GetBytes(AES_KEY));
byte[] ivData = md5.ComputeHash(Encoding.UTF8.GetBytes(AES_IV));
byte[] dataByteArray = Encoding.UTF8.GetBytes(text);
using (MemoryStream ms = new MemoryStream())
{
using (
CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(keyData, ivData), CryptoStreamMode.Write)
)
{
cs.Write(dataByteArray, 0, dataByteArray.Length);
cs.FlushFinalBlock();
encrypt = Convert.ToBase64String(ms.ToArray());
}
}
return encrypt;
}
catch
{
return text;
}
}
/// <summary>
/// AES解密
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public string AESDecrypt(string text)
{
var decrypt = "";
try
{
SymmetricAlgorithm aes = new AesCryptoServiceProvider();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider();
byte[] keyData = sha256.ComputeHash(Encoding.UTF8.GetBytes(AES_KEY));
byte[] ivData = md5.ComputeHash(Encoding.UTF8.GetBytes(AES_IV));
byte[] dataByteArray = Convert.FromBase64String(text);
using (MemoryStream ms = new MemoryStream())
{
using (
CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(keyData, ivData), CryptoStreamMode.Write)
)
{
cs.Write(dataByteArray, 0, dataByteArray.Length);
cs.FlushFinalBlock();
decrypt = Encoding.UTF8.GetString(ms.ToArray());
}
}
return decrypt;
}
catch
{
return text;
}
}
}
/// <summary>
/// 回傳結果
/// </summary>
/// <typeparam name="T">資料型別</typeparam>
public class ApiResult<T>
{
public string Code { get; set; }
public string Msg { get; set; }
public T Data { get; set; }
}
/// <summary>
/// 資料夾
/// </summary>
public class FolderFunction
{
/// <summary>
/// 創建資料夾
/// </summary>
/// <param name="folderPath"></param>
/// <param name="tempType">0:找到資料夾也不刪除 1:找到資料夾並且刪除</param>
public void CreateFolder(string folderPath, int type)
{
DirectoryInfo dInfo = new DirectoryInfo(folderPath);
if (dInfo.Exists) //找到
{
if (type == 1)
{
dInfo.Delete(true); //如果資料夾裡面有檔案給bool參數就可以直接刪除沒給bool參數會報錯誤
}
dInfo.Create();
}
else //沒找到
{
dInfo.Create(); //建立新的資料夾
}
}
/// <summary>
/// 刪除檔案
/// </summary>
/// <param name="filePath"></param>
public void DeleteFile(string filePath)
{
System.IO.FileInfo file = new System.IO.FileInfo(filePath);
if (File.Exists(filePath)) //找到
{
//do something
file.Delete();
}
else //沒找到
{
//do something
}
}
}
}

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class SystemCategory
{
}
public class SystemMain : Actor
{
public string Main_system_guid { get; set; }
public byte Deleted { get; set; }
public string Full_name { get; set; }
public int Priority { get; set; }
public string Code { get; set; }
}
public class SystemSub : Actor
{
public string Sub_system_guid { get; set; }
public string Main_system_guid { get; set; }
public byte Deleted { get; set; }
public string Full_name { get; set; }
public int Priority { get; set; }
}
public class Device_item : Actor
{
public string device_item_guid { get; set; }
public string sub_system_guid { get; set; }
public string full_name { get; set; }
public string points { get; set; }
public string unit { get; set; }
public byte is_show { get; set; }
public byte is_show_riserDiagram { get; set; }
public byte is_controll { get; set; }
public byte is_bool { get; set; }
}
public class Checksame
{
public string sub_system_guid { get; set; }
public string points { get; set; }
public string device_item_guid { get; set; }
}
public class Tags
{
public string device_building_tag { get; set; }
public string device_system_tag { get; set; }
public string device_name_tag { get; set; }
}
public class Deletebool
{
public string Reason { get; set; }
public bool Delete { get; set; }
}
public class GetCheckName
{
public string msname { get; set; }
public string bname { get; set; }
public string subname { get; set; }
public string device_name_tag { get; set; }
}
public class guidandsubguid
{
public string guid { get; set; }
public string subguid { get; set; }
}
}

166
Backend/Models/UserInfo.cs Normal file
View File

@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public enum UserStatusEnum : byte
{
Suspend = 0, //停權
Normal = 1, //正常
}
public class UserInfo : Actor
{
public string Userinfo_guid { get; set; }
public byte Deleted { get; set; } //是否刪除
public byte Status { get; set; } //狀態
public string StatusText //狀態文字
{
get
{
Dictionary<int, string> pairs = new Dictionary<int, string>()
{
{ 0, "停權"},
{ 1, "正常"},
};
return pairs[Status];
}
}
public string Role_guid { get; set; } //角色guid
public string Full_name { get; set; } //姓名
public string Account { get; set; } //帳號
public string Password { get; set; } //密碼
public string Tel { get; set; } //市話
public string Phone { get; set; } //手機
public string Email { get; set; } //信箱
}
public class UserManagerList : Actor
{
public string Userinfo_guid { get; set; }
public string Full_name { get; set; } //姓名
public string Role_full_name { get; set; } //角色名稱
public string Email { get; set; } //信箱
public string Phone { get; set; } //手機
public string Account { get; set; }
public byte Layer { get; set; }
}
public class RoleManagerList : Actor
{
public string Role_guid { get; set; }
public string Full_name { get; set; } //姓名
public byte Layer { get; set; }
}
public class SaveUserManager
{
public string Id { get; set; }
public string Name { get; set; } //姓名
public string Email { get; set; } //信箱
public string Account { get; set; } //帳號
public string Phone { get; set; } //手機號碼
public string RoleId { get; set; } //角色GUID
}
public class SimpleUser
{
public string Full_name { get; set; } //姓名
public string Account { get; set; } //帳號
public string Email { get; set; } //信箱
public string Phone { get; set; } //手機
public string Role_guid { get; set; } //角色GUID
}
public class PostRole
{
public string Id { get; set; }
public string Name { get; set; }
}
public class SimpleRole
{
public string Full_name { get; set; } //姓名
}
public class RoleAuthList : Actor
{
public string Role_guid { get; set; } //角色GUID
public string AuthCode { get; set; } //權限代碼
public string Role_full_name { get; set; } //角色名稱
public int AuthType { get; set; } //角色類型 1:前台 2:後台
public string AuthTypeText //角色類型文字
{
get {
Dictionary<int, string> pairs = new Dictionary<int, string>()
{
{ 1, "前台"},
{ 2, "後台"},
};
return pairs[AuthType];
}
}
public string MainName { get; set; } //大項名稱
public string SubName { get; set; } //功能名稱
public string Building_full_name { get; set; } //區域名稱
}
public class PostRoleAuthFilter
{
public string SelectedRoleId { get; set; }
public string SelectedAuthType { get; set; }
public string SelectedBuild { get; set; }
}
public class AuthPage
{
public string AuthCode { get; set; }
public string MainName { get; set; }
public string SubName { get; set; }
}
public class PostSaveRoleAuth
{
public string SelectedRoleId { get; set; }
public List<string> SaveCheckAuth { get; set; }
//public FrontEndCheckAuth BackEndCheckAuth { get; set; }
}
public class PostDeleteRoleAuth
{
public string RoleId { get; set; }
public string AuthCode { get; set; }
}
//public class FrontEndCheckAuth
//{
// public string Building { get; set; }
// public List<string> SelectedAuth { get; set; }
//}
public class Auth_page
{
public string AuthCode { get; set; }
public byte AuthType { get; set; }
public string MainName { get; set; }
public string SubName { get; set; }
public string building_guid { get; set; }
public string ShowView { get; set; }
public string created_at { get; set; }
}
public class JwtLogin
{
public string userinfo_guid { get; set; }
public string account { get; set; }
public string full_name { get; set; }
public string email { get; set; }
}
public class JwtGet : JwtLogin
{
public int nbf { get; set; }
public int exp { get; set; }
}
}

View File

@ -0,0 +1,274 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend.Models
{
public class WeatherAPIJob
{
}
public class Publicclass
{
public string Success { get; set; }
public Result Result { get; set; }
}
public class Result
{
public string Resource_id { get; set; }
public List<FieldsItem> Fields { get; set; }
}
public class FieldsItem
{
public string Id { get; set; }
public string Type { get; set; }
}
//臺灣各縣市鄉鎮未來3天(72小時)逐3小時天氣預報
public class Root: Publicclass
{
public Records1 Records { get; set; }
}
#region 3(72)3
public class Records1 // 臺灣各縣市鄉鎮未來3天(72小時)逐3小時天氣預報
{
//public string DatasetDescription { get; set; }
public List<LocationsItem> Locations { get; set; }
}
public class LocationsItem
{
public string DatasetDescription { get; set; }
public string LocationsName { get; set; }
public string Dataid { get; set; }
public List<LocationDetail> Location { get; set; }
}
public class LocationDetail
{
public string LocationName { get; set; }
public string Geocode { get; set; }
public string Lat { get; set; }
public string Lon { get; set; }
public List<WeatherElementItem> WeatherElement { get; set; }
}
public class WeatherElementItem
{
public string ElementName { get; set; }
public string Description { get; set; }
public List<TimeItem> Time { get; set; }
}
public class TimeItem
{
//public string StartTime;
public string StartTime { get; set; }
//public string EndTime;
public string EndTime { get; set; }
public string DataTime { get; set; }
public List<ElementValueItem> ElementValue { get; set; }
}
public class ElementValueItem
{
public string Value { get; set; }
public string Measures { get; set; }
}
#endregion
public class ShowWeather
{
public int id { get; set; }
public string weather_type { get; set; }
public string get_value { get; set; }
}
#region alert
public class alert
{
public string identifier { get; set; }
public string sender { get; set; }
public string sent { get; set; }
public string status { get; set; }
public string msgtype { get; set; }
public string scope { get; set; }
public string references { get; set; }
public info info { get; set; }
}
public class info
{
public string language { get; set; }
public string category { get; set; }
public string Event { get; set; }
public string urgency { get; set; }
public string severity { get; set; }
public string certainty { get; set; }
public values eventcode { get; set; }
public string effective { get; set; }
public string onset { get; set; }
public string expires { get; set; }
public string senderName { get; set; }
public string headline { get; set; }
public string description { get; set; }
public string instruction { get; set; }
public string web { get; set; }
public values parameter { get; set; }
public List<areas> area { get; set; }
}
public class values
{
public string valuename { get; set; }
public string value { get; set; }
}
public class areas
{
public string areaDesc { get; set; }
public values geocode { get; set; }
}
#endregion
#region -
public class Root2 : Publicclass
{
public Records2 Records { get; set; }
}
public class Records2
{
public string DatasetDescription { get; set; }
public List<Earthquake> Earthquake { get; set; }
}
public class Earthquake
{
public int EarthquakeNo { get; set; }
public string ReportType { get; set; }
public string ReportColor { get; set; }
public string ReportContent { get; set; }
public string ReportImageURI { get; set; }
public string ReportRemark { get; set; }
public string Web { get; set; }
public string ShakemapImageURI { get; set; }
public EarthquakeInfo EarthquakeInfo { get; set; }
public Intensity Intensity { get; set; }
}
public class EarthquakeInfo
{
public string OriginTime { get; set; }
public string Source { get; set; }
public Depth Depth { get; set; }
public EpiCenter EpiCenter { get; set; }
public Magnitude Magnitude { get; set; }
}
public class Depth
{
public string Value { get; set; }
public string Unit { get; set; }
}
public class EpiCenter
{
public string Location { get; set; }
public Depth EpiCenterLat { get; set; }
public Depth EpiCenterLon { get; set; }
}
public class Magnitude
{
public string MagnitudeType { get; set; }
public double MagnitudeValue { get; set; }
}
public class Intensity
{
public List<ShakingArea> ShakingArea { get; set; }
}
public class ShakingArea
{
public string AreaDesc { get; set; }
public string AreaName { get; set; }
public string InfoStatus { get; set; }
public Depth AreaIntensity { get; set; }
}
#endregion
#region XML
public partial class RainAPI
{
public Alert Alert { get; set; }
}
public partial class RainAPIInfoList
{
public Alert2 Alert { get; set; }
}
public partial class Alert
{
public string Xmlns { get; set; }
public string Identifier { get; set; }
public string Sender { get; set; }
public DateTimeOffset Sent { get; set; }
public string Status { get; set; }
public string MsgType { get; set; }
public string Scope { get; set; }
public string References { get; set; }
public Info Info { get; set; }
}
public partial class Alert2
{
public string Xmlns { get; set; }
public string Identifier { get; set; }
public string Sender { get; set; }
public DateTimeOffset Sent { get; set; }
public string Status { get; set; }
public string MsgType { get; set; }
public string Scope { get; set; }
public string References { get; set; }
public List<Info> Info { get; set; }
}
public partial class Info
{
public string Language { get; set; }
public string Category { get; set; }
public string Event { get; set; }
public string Urgency { get; set; }
public string Severity { get; set; }
public string Certainty { get; set; }
public EventCode EventCode { get; set; }
public DateTimeOffset Effective { get; set; }
public DateTimeOffset Onset { get; set; }
public DateTimeOffset Expires { get; set; }
public string SenderName { get; set; }
public string Headline { get; set; }
public string Description { get; set; }
public string Instruction { get; set; }
public string Web { get; set; }
//public EventCode Parameter { get; set; }
public List<Area> Area { get; set; }
}
public partial class Area
{
public string AreaDesc { get; set; }
public EventCode Geocode { get; set; }
}
public partial class EventCode
{
public string ValueName { get; set; }
public string Value { get; set; }
}
#endregion
}

26
Backend/Program.cs Normal file
View File

@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Backend
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

View File

@ -0,0 +1,29 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51127",
"sslPort": 44376
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
}
},
"Backend": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

View File

@ -0,0 +1,179 @@
using Backend.Models;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
namespace Backend.Services.Implement
{
/*
*
*/
public class BackgroundService
{
private readonly IBackendRepository backendRepository;
private List<string> mode_list = new List<string>() { "insert", "insert_list", "update", "update_list", "delete", "purge_all_insert", "purge" };
public BackgroundService(IBackendRepository backendRepository)
{
this.backendRepository = backendRepository;
}
/// <summary>
/// 加入至背景執行任務(單筆情況)
/// </summary>
/// <param name="building_ip"></param>
/// <param name="building_guid"></param>
/// <param name="target_table"></param>
/// <param name="mode"></param>
/// <param name="parameter"></param>
/// <param name="fileInfos"></param>
/// <returns></returns>
public async Task AddTask(string building_ip = "", string building_guid = "", string target_table = "", string mode = "", Dictionary<string, object> parameter = null, List<Models.FileInfo> fileInfos = null)
{
List<string> temp_ips = new List<string>();
if (!string.IsNullOrEmpty(building_ip))
{
//有填寫IP直接用
temp_ips.Add(building_ip);
}
else if (!string.IsNullOrEmpty(building_guid))
{
//未填寫IP抓取該棟別IP
var building_where = @"deleted = 0 AND building_guid = @Building_guid";
var building = await backendRepository.GetOneAsync<BuildInfo>("building", building_where, new { Building_guid = building_guid });
temp_ips.Add(building.Ip_address_port);
}
else
{
//未填寫IP、棟別guid 代表全抓
var building_where = @"deleted = 0";
var buildInfos = await backendRepository.GetAllAsync<BuildInfo>("building", building_where);
foreach(var build in buildInfos)
{
temp_ips.Add(build.Ip_address_port);
}
}
if(temp_ips != null && temp_ips.Count > 0)
{
foreach(var temp_ip in temp_ips)
{
if (!string.IsNullOrEmpty(temp_ip) && !string.IsNullOrEmpty(target_table) && mode_list.Contains(mode.ToLower()))
{
Dictionary<string, object> backgroundServiceTaskDic = new Dictionary<string, object>()
{
{ "@task_type", 1},
{ "@target_ip", temp_ip},
{ "@target_table", target_table},
{ "@mode", mode.ToLower()},
{ "@repeat_times", 0},
{ "@is_complete", 0},
};
if (parameter != null)
{
var data_json = JsonSerializer.Serialize(parameter);
if (!string.IsNullOrEmpty(data_json))
{
backgroundServiceTaskDic.Add("@target_data", data_json);
}
}
if (fileInfos != null && fileInfos.Count > 0)
{
var file_json = JsonSerializer.Serialize(fileInfos);
if (!string.IsNullOrEmpty(file_json))
{
backgroundServiceTaskDic.Add("@target_files", file_json);
}
}
await backendRepository.AddOneByCustomTable(backgroundServiceTaskDic, "background_service_task");
}
}
}
}
/// <summary>
/// 加入至背景執行任務(多筆情況)
/// </summary>
/// <param name="building_ip"></param>
/// <param name="building_guid"></param>
/// <param name="target_table"></param>
/// <param name="mode"></param>
/// <param name="parameter"></param>
/// <param name="fileInfos"></param>
/// <returns></returns>
public async Task AddTask(string building_ip = "", string building_guid = "", string target_table = "", string mode = "", List<Dictionary<string, object>> parameter = null, List<Models.FileInfo> fileInfos = null)
{
List<string> temp_ips = new List<string>();
if (!string.IsNullOrEmpty(building_ip))
{
//有填寫IP直接用
temp_ips.Add(building_ip);
}
else if (!string.IsNullOrEmpty(building_guid))
{
//未填寫IP抓取該棟別IP
var building_where = @"deleted = 0 AND building_guid = @Building_guid";
var building = await backendRepository.GetOneAsync<BuildInfo>("building", building_where, new { Building_guid = building_guid });
temp_ips.Add(building.Ip_address_port);
}
else
{
//未填寫IP、棟別guid 代表全抓
var building_where = @"deleted = 0";
var buildInfos = await backendRepository.GetAllAsync<BuildInfo>("building", building_where);
foreach (var build in buildInfos)
{
temp_ips.Add(build.Ip_address_port);
}
}
if (temp_ips != null && temp_ips.Count > 0)
{
foreach (var temp_ip in temp_ips)
{
if (!string.IsNullOrEmpty(temp_ip) && !string.IsNullOrEmpty(target_table) && mode_list.Contains(mode.ToLower()))
{
Dictionary<string, object> backgroundServiceTaskDic = new Dictionary<string, object>()
{
{ "@task_type", 1},
{ "@target_ip", temp_ip},
{ "@target_table", target_table},
{ "@mode", mode.ToLower()},
{ "@repeat_times", 0},
{ "@is_complete", 0},
};
if (parameter != null)
{
var data_json = JsonSerializer.Serialize(parameter);
if (!string.IsNullOrEmpty(data_json))
{
backgroundServiceTaskDic.Add("@target_data", data_json);
}
}
if (fileInfos != null && fileInfos.Count > 0)
{
var file_json = JsonSerializer.Serialize(fileInfos);
if (!string.IsNullOrEmpty(file_json))
{
backgroundServiceTaskDic.Add("@target_files", file_json);
}
}
await backendRepository.AddOneByCustomTable(backgroundServiceTaskDic, "background_service_task");
}
}
}
}
}
}

181
Backend/Startup.cs Normal file
View File

@ -0,0 +1,181 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Repository.Helper;
using Repository.BackendRepository.Implement;
using Repository.BackendRepository.Interface;
using Repository.BaseRepository.Implement;
using Repository.BaseRepository.Interface;
using Repository.FrontendRepository.Implement;
using Repository.FrontendRepository.Interface;
using Repository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Backend.Jwt;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System.IdentityModel.Tokens.Jwt;
namespace Backend
{
public class Startup
{
public DBConfig dBConfig = new DBConfig()
{
MSSqlDBConfig = new MSSqlDBConfig(),
MySqlDBConfig = new MySqlDBConfig()
};
public Startup(IConfiguration configuration)
{
Configuration = configuration;
#region MSSql DB Config
//dBConfig.MSSqlDBConfig.Server = Configuration.GetValue<string>("DBConfig:MSSqlDBConfig:Server");
//dBConfig.MSSqlDBConfig.Port = Configuration.GetValue<string>("DBConfig:MSSqlDBConfig:Port");
//dBConfig.MSSqlDBConfig.Root = Configuration.GetValue<string>("DBConfig:MSSqlDBConfig:Root");
//dBConfig.MSSqlDBConfig.Password = Configuration.GetValue<string>("DBConfig:MSSqlDBConfig:Password");
//dBConfig.MSSqlDBConfig.Database = Configuration.GetValue<string>("DBConfig:MSSqlDBConfig:Database");
#endregion MSSql DB Config
#region MySql DB Config
dBConfig.MySqlDBConfig.Server = Configuration.GetValue<string>("DBConfig:MySqlDBConfig:Server");
dBConfig.MySqlDBConfig.Port = Configuration.GetValue<string>("DBConfig:MySqlDBConfig:Port");
dBConfig.MySqlDBConfig.Root = Configuration.GetValue<string>("DBConfig:MySqlDBConfig:Root");
dBConfig.MySqlDBConfig.Password = Configuration.GetValue<string>("DBConfig:MySqlDBConfig:Password");
dBConfig.MySqlDBConfig.Database = Configuration.GetValue<string>("DBConfig:MySqlDBConfig:Database");
#endregion MySql DB Config
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddLogging(
builder =>
{
builder.AddFilter("Microsoft", LogLevel.Warning)
.AddFilter("System", LogLevel.Warning)
.AddFilter("NToastNotify", LogLevel.Warning)
.AddConsole();
});
#region DBHelper
services.Configure<DBConfig>(Configuration.GetSection("DBConfig"));
services.AddTransient<IDatabaseHelper, DatabaseHelper>();
#endregion DBHelper
#region Repository
services.AddTransient<IBackendRepository, BackendRepository>();
services.AddTransient<IFrontendRepository, FrontendRepository>();
services.AddTransient<IBaseRepository, BaseRepository>();
services.AddTransient<IUserInfoRepository, UserInfoRepository>();
services.AddTransient<IDeviceManageRepository, DeviceManageRepository>();
services.AddTransient<IDeviceImportRepository, DeviceImportRepository>();
#endregion Repository
#region JWT
services.AddTransient<IJwtHelpers, JwtHelpers>();
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// 當驗證失敗時,回應標頭會包含 WWW-Authenticate 標頭,這裡會顯示失敗的詳細錯誤原因
options.IncludeErrorDetails = true; // 預設值為 true有時會特別關閉
options.TokenValidationParameters = new TokenValidationParameters()
{
// 透過這項宣告,就可以從 "sub" 取值並設定給 User.Identity.Name
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
// 透過這項宣告,就可以從 "roles" 取值,並可讓 [Authorize] 判斷角色
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
// 一般我們都會驗證 Issuer
ValidateIssuer = true,
ValidIssuer = Configuration.GetValue<string>("JwtSettings:Issuer"),
RequireExpirationTime = true,
// 通常不太需要驗證 Audience
ValidateAudience = false,
//ValidAudience = "JwtAuthDemo", // 不驗證就不需要填寫
// 一般我們都會驗證 Token 的有效期間
ValidateLifetime = true,
// 如果 Token 中包含 key 才需要驗證,一般都只有簽章而已
ValidateIssuerSigningKey = false,
// "1234567890123456" 應該從 IConfiguration 取得
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetValue<string>("JwtSettings:SignKey")))
};
});
#endregion JWT
double loginExpireMinute = this.Configuration.GetValue<double>("LoginExpireMinute");
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(loginExpireMinute);
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddFile("Logs/log-{Date}.txt");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true) // allow any origin
.AllowCredentials());
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Login}/{action=Index}/{id?}");
});
}
}
}

View File

@ -0,0 +1,609 @@
@{
ViewData["MainNum"] = "1";
ViewData["SubNum"] = "2";
ViewData["Title"] = "區域設定";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">區域資料管理</a></li>
<li class="breadcrumb-item active">區域基本資料</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-xl-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
@*<div class="subheader">
<h1 class="subheader-title">
<img src="img/asus.png" id="company-logo"><span id="company-name">華碩電腦</span>
</h1>
</div>*@
<ul class="nav nav-tabs" id="tabs" role="tablist">
<li class="nav-item"><a class="nav-link active" data-toggle="tab" href="#tab-build-info" role="tab"><span class="hidden-sm-down ml-1">區域基本資料</span></a></li>
<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#tab-build-floor" role="tab"><span class="hidden-sm-down ml-1">樓層設定</span></a></li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane fade show active" id="tab-build-info" role="tabpanel" aria-labelledby="tab-build-info">
@Html.Partial("_BuildInfo")
</div>
<div class="tab-pane fade" id="tab-build-floor" role="tabpanel" aria-labelledby="tab-build-floor">
@Html.Partial("_BuildFloor")
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var buildInfoTable, buildFloorTable;
var selected_build_guid;
var selected_build_guid_top = "";
var selected_build_guid_top_name;
var selected_floor_guid = "";
//#region 區域基本資料 document ready
$(function () {
//#region 區域基本資料 DataTable
buildInfoTable = $("#buildInfo_table").DataTable({
"rowReorder": {
"dataSrc": "priority"
},
"columns": [
{
"data": "building_guid",
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "priority",
"className": "reorder",
"visible": false
},
{
"data": "full_name"
},
{
"data": "ip_address"
},
{
"data": "ip_port"
},
{
"data": "floorNum"
},
{
"data": "created_at"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
//"order": [[2, "desc"]],
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-guid', data.building_guid);
},
"ajax": {
"url": "/BuildInfo/BuildInfoList",
"type": "POST",
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
//樓層設定上方選單
$("#BuildList").empty();
$.each(data, function (key, value) {
$("#BuildList").append(`<button type="button" class="btn btn-outline-success waves-effect waves-themed ml-2 mb-2 btn-station" id="${value.building_guid}" onclick="clickBuilding('${value.building_guid}')">${value.full_name}</button>`);
@*if (key == 0) {
selected_build_guid_top_name = value.full_name;
$("#BuildList").append(`<button type="button" class="btn btn-success waves-effect waves-themed ml-2 mb-2 btn-station" id="${value.building_guid}" onclick="clickBuilding('${value.building_guid}')">${value.full_name}</button>`);
}
else {
$("#BuildList").append(`<button type="button" class="btn btn-outline-success waves-effect waves-themed ml-2 mb-2 btn-station" id="${value.building_guid}" onclick="clickBuilding('${value.building_guid}')">${value.full_name}</button>`);
}*@
});
return data;
}
}
});
//#endregion
buildInfoTable.on("row-reorder", function (e, diff, edit) {
var exchangeList = [];
for (var i = 0, len = diff.length; i < len; i++) {
var rowData = buildInfoTable.row(diff[i].node).data();
var obj = {
building_guid: rowData.building_guid,
priority: diff[i].newData
}
exchangeList.push(obj);
}
var url = "/BuildInfo/ChangeBuildInfoPriority";
var send_data = {
BuildInfoPriorities: exchangeList
}
$.post(url, send_data, function (rel) {
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);
}
}, "json");
});
//#region 修改區域基本資料
$('#buildInfo_table').on("click", "button.edit-btn", function () {
selected_build_guid = $(this).parents('tr').attr('data-guid');
$('#build-modal .modal-title').html("區域基本資料 - 修改");
$('#build_name_modal').val($(this).parents('tr')[0].children[1].innerText);
$('#ip_address_modal').val($(this).parents('tr')[0].children[2].innerText);
$('#ip_port_modal').val($(this).parents('tr')[0].children[3].innerText);
$('#build-modal').modal();
});
//#endregion
//#region 刪除區域基本資料
$('#buildInfo_table').on("click", "button.del-btn", function () {
selected_build_guid = $(this).parents('tr').attr('data-guid');
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/BuildInfo/DeleteOneBuild/";
var send_data = {
guid: selected_build_guid
}
$.post(url, send_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else if (rel.code == "9997") {
var htnl = rel.msg + "<br>"
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: htnl,
});
}
else {
toast_ok(rel.msg);
buildInfoTable.ajax.reload(null, false);
}
}, 'json');
}
});
});
//#endregion
});
//#endregion
//#region 新增區域基本資料
function AddBuild() {
selected_build_guid = "0";
BuildInfoValidate.resetForm();
$("#build-modal .modal-title").html("區域基本資料 - 新增");
$("#build-form").trigger("reset");
$("#build-modal").modal();
}
//#endregion
//#region 區域表單驗證
var BuildInfoValidate = $("#build-form").validate({
rules: {
build_name_modal: {
required: true,
maxlength: 50,
filterspace: true
},
ip_address_modal: {
required: true,
maxlength: 50,
filterspace: true
},
ip_port_modal: {
required: true,
maxlength: 50,
filterspace: true
}
}
});
//#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 send_data = {
Building_guid: selected_build_guid,
Full_name: $('#build_name_modal').val(),
Ip_address: $('#ip_address_modal').val(),
Ip_port: $('#ip_port_modal').val()
}
$.post(url, send_data, 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;
}
}, 'json')
.fail(function (xhr, status, error) {
$("#save-building-btn").html('確定').attr("disabled", false);
});
}
}
//#endregion
</script>
<script>
//#region 樓層設定 document ready
$(function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href") // activated tab
if (target == "#tab-build-floor") {
$("#BuildList").find("button").first().click();
}
});
//#region 樓層設定 DataTable
buildFloorTable = $("#buildFloor_table").DataTable({
"rowReorder": {
"dataSrc": "priority"
},
"pageLength": 50,
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "priority",
"className": "reorder",
"visible": false
},
{
"data": null,
"render": function (data, type, row, meta) {
return selected_build_guid_top_name;
}
},
{
"data": "full_name"
},
{
"data": "initMapName"
},
{
"data": "created_at"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
@*"order": [[1, "desc"]],*@
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-guid', data.floor_guid);
},
"ajax": {
"url": "/BuildInfo/BuildFloorList",
"type": "POST",
"data": function (d) {
d.BuildGuid = selected_build_guid_top;
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
//#endregion
//#region 修改樓層排序
buildFloorTable.on("row-reorder", function (e, diff, edit) {
var exchangeList = [];
for (var i = 0, len = diff.length; i < len; i++) {
var rowData = buildFloorTable.row(diff[i].node).data();
var obj = {
floor_guid: rowData.floor_guid,
priority: diff[i].newData
}
exchangeList.push(obj);
}
var url = "/BuildInfo/ChangeFloorPriority";
var send_data = {
FloorPriorities: exchangeList
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
toast_ok(rel.msg);
buildFloorTable.ajax.reload(null, false);
}
}, "json");
});
//#endregion
//#region 修改樓層設定
$('#buildFloor_table').on("click", "button.edit-btn", function () {
selected_floor_guid = $(this).parents('tr').attr('data-guid');
$('#floor-modal .modal-title').html("樓層設定 - 修改");
//取得單一樓層設定
var url = "/BuildInfo/GetOneBuildFloor";
var send_data = {
guid: selected_floor_guid
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
$("#BuildName").html(selected_build_guid_top_name);
$("#floor_name_modal").val(rel.data.full_name);
@*$("#map_file_preview_modal").attr("data-original", rel.data.mapUrl);*@
$('#floor-modal').modal();
}
}, 'json');
});
//#endregion
//#region 刪除樓層設定
$('#buildFloor_table').on("click", "button.del-btn", function () {
selected_floor_guid = $(this).parents('tr').attr('data-guid');
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
//取得單一系統管理員
var url = "/BuildInfo/DeleteOneFloor/";
var send_data = {
guid: selected_floor_guid
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else if (rel.code == "9997") {
var htnl = rel.msg + "<br>" + rel.data
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: htnl,
});
}
else {
toast_warning(rel.msg);
}
return;
}
else {
toast_ok(rel.msg);
floorTableReload();
return;
}
}, 'json');
}
});
});
//#endregion
});
//#endregion
//#region 樓層DataTable Reload
function floorTableReload() {
buildFloorTable.ajax.reload(null, false);
}
//#endregion
//#region 樓層設定 - 選擇區域
function clickBuilding(guid) {
selected_build_guid_top = guid;
selected_build_guid_top_name = $(`#${guid}`).text();
if ($('#BuildList').find('.btn-station').hasClass("btn-success")) {
$('#BuildList').find('.btn-station').removeClass("btn-success").addClass("btn-outline-success");
}
$(`#${guid}`).removeClass("btn-outline-success").addClass("btn-success");
floorTableReload();
}
//#endregion
//#region 新增樓層設定
function AddFloor() {
selected_floor_guid = "";
FloorValidate.resetForm();
$("#floor-modal .modal-title").html("樓層設定 - 新增");
$("#floor-form").trigger("reset");
$("#BuildName").html(selected_build_guid_top_name);
$("#floor-modal").modal();
}
//#endregion
//#region 樓層設定表單驗證
var FloorValidate = $("#floor-form").validate({
rules: {
floor_name_modal: {
required: true,
maxlength: 50,
filterspace: true
},
map_file_modal: {
accept: "image/svg+xml"
}
}
});
//驗證是否有上傳
jQuery.validator.addMethod("fileUpload", function (value, element) {
var str = value;
var result = false;
if ($("#map_file_modal")[0].files.length > 0) {
result = true;
}
else {
result = false;
}
return result;
}, "請選擇檔案");
//#endregion
//#region 儲存樓層設定
function SaveFloor() {
if ($("#floor-form").valid()) {
$("#save-floor-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
var url = "/BuildInfo/SaveBuildFloor";
var formData = new FormData();
maps = $('#map_file_modal')[0].files
formData.append("Floor_guid", selected_floor_guid);
formData.append("Building_guid", selected_build_guid_top);
formData.append("Full_name", $('#floor_name_modal').val());
if (maps.length > 0) {
var file_names = maps[0].name.split(".")
formData.append("MapFile", maps[0])
formData.append("InitMapName", maps[0].name.replace("." + file_names[file_names.length - 1], ""));
}
$.ajax({
type: "POST",
url: url,
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (rel) {
$("#save-floor-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);
floorTableReload();
$('#floor-modal').modal('hide');
return;
}
},
fail: function (jqXHR, textStatus, errorThrown) {
$("#save-floor-btn").html('確定').attr("disabled", false);
}
});
}
}
//#endregion
//#region 變更樓層平面圖
function changeImage(input) {
$(`#map_file_preview_modal`).attr("data-src", window.URL.createObjectURL(input.files[0]));
}
//#endregion
</script>
}

View File

@ -0,0 +1,69 @@
<div class="row mb-3" id="BuildList">
@*<button type="button" class="btn btn-outline-success waves-effect waves-themed ml-2 mb-2 btn-station" id="AAA">123</button>
<button type="button" class="btn btn-success waves-effect waves-themed ml-2 mb-2 btn-station" id="BBB">456</button>*@
</div>
<div class="row">
<div class="col-12 d-flex justify-content-end">
<a href="javascript:;" class="btn btn-success waves-effect waves-themed mb-3" onclick="AddFloor()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="buildFloor_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>排序</th>
<th>區域名稱</th>
<th>樓層</th>
<th>地圖檔</th>
<th>建立時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- Modal 樓層設定 -->
<div class="modal fade" id="floor-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
樓層設定 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form class="user-form" id="floor-form">
<div class="row">
<div class="form-group col-12">
<label class="form-label">區域名稱</label>
<h6 id="BuildName"></h6>
</div>
<div class="form-group col-12">
<label class="form-label" for="floor_name_modal"><span class="text-danger">*</span>樓層</label>
<input type="text" id="floor_name_modal" class="form-control" name="floor_name_modal">
</div>
<div class="form-group col-12">
<label class="form-label" for="map_file_modal">平面圖檔(限制SVG格式)</label>
<input type="file" id="map_file_modal" class="form-control" name="map_file_modal" onchange="changeImage(this)" accept="image/svg+xml">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="save-floor-btn" onclick="SaveFloor()">確定</button>
</div>
</div>
</div>
</div>
<!-- /.Modal 樓層設定 -->

View File

@ -0,0 +1,65 @@
<div class="row mb-3">
<div class="col-12 d-flex justify-content-end">
<a href="javascript:;" class="btn btn-success waves-effect waves-themed mb-3" id="addUser-btn" onclick="AddBuild()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="buildInfo_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>排序</th>
<th>區域名稱</th>
<th>監控主機 IP</th>
<th>監控主機 PORT</th>
<th>樓層數量</th>
<th>建立時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- Modal 區域基本資料 -->
<div class="modal fade" id="build-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
區域基本資料 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form class="user-form" id="build-form">
<div class="row">
<div class="form-group col-12">
<label class="form-label" for="build_name_modal"><span class="text-danger">*</span>區域名稱</label>
<input type="text" id="build_name_modal" class="form-control" name="build_name_modal">
</div>
<div class="form-group col-12">
<label class="form-label" for="ip_address_modal"><span class="text-danger">*</span>監控主機 IP</label>
<input type="text" id="ip_address_modal" class="form-control" name="ip_address_modal">
</div>
<div class="form-group col-12">
<label class="form-label" for="ip_port_modal"><span class="text-danger">*</span>監控主機 PORT</label>
<input type="text" id="ip_port_modal" class="form-control" name="ip_port_modal">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="save-building-btn" onclick="SaveBuild()">確定</button>
</div>
</div>
</div>
</div>
<!-- /.Modal 區域基本資料 -->

View File

@ -0,0 +1,992 @@
@{
ViewData["MainNum"] = "1";
ViewData["SubNum"] = "3";
ViewData["Title"] = "區域選單管理";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">首頁</a></li>
<li class="breadcrumb-item active">區域選單管理</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<div class="subheader">
<h1 class="subheader-title">
<span>區域選單設定</span>
</h1>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<div class="btn-group btn-group-md" id="buildlist">
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3">
<div class="pr-3 ">
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AllMainSys()">全選</button>
</div>
<div class="pr-3 row col">
<div class="frame-wrap" id="mainlist">
</div>
</div>
<div class="card border mb-g w-100 mb-5" id="menucard">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-between">
<div class="card-title font-weight-bold">選單</div>
<div class="text-right ">
<a href="javascript:;" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" id="addUser-btn" onclick="Addmenu()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="buildMenu_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>系統大類</th>
<th>系統小類</th>
<th>預設頁面</th>
<th>是否顯示<br>平面圖</th>
<th>昇位圖<br>詳細資料設定</th>
<th>昇位圖<br>詳細資料URL</th>
@*<th>昇位圖URL</th>*@
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="card border mb-g w-100 mb-5" id="floorcard">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-between">
<div class="card-title font-weight-bold">樓層設定</div>
<div class="text-right ">
<a href="javascript:;" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" id="addUser-btn" onclick="AddFloor()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="buildMenu_floor_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>系統大類</th>
<th>系統小類</th>
<th>樓層</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="build-menu-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
選單基本資料 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form id="build-menu-form">
<div class="row">
<div class="form-group col-6">
<label class="form-label" for="build_menu_building_modal"><span class="text-danger">*</span>棟別</label>
<select class="form-control" id="build_menu_building_modal">
</select>
</div>
<div class="form-group col-6">
<label class="form-label" for="build_menu_main_modal"><span class="text-danger">*</span>大類</label>
<select class="form-control" id="build_menu_main_modal">
</select>
</div>
<div class="form-group col-12">
<label class="form-label" for="build_menu_sub_modal"><span class="text-danger">*</span>小類</label>
<select class="form-control" id="build_menu_sub_modal">
</select>
</div>
<div class="form-group col-12">
<label class="form-label"><span class="text-danger">*</span>預設頁面</label>
<div class="row" id="build_menu_drawing_modal">
<div class="col">
<input type="radio" name="drawing" id="drawing_4" value="4" checked>
<label for="drawing_4">
昇位圖
</label>
</div>
<div class="col">
<input type="radio" name="drawing" id="drawing_2" value="2">
<label for="drawing_2">
系統圖
</label>
</div>
<div class="col" id="drawing_1_div" style="display: none;">
<input type="radio" name="drawing" id="drawing_1" value="1">
<label for="drawing_1">
樓層平面圖
</label>
</div>
</div>
</div>
<div class="form-group col-12" id="" name="drawing_extend">
<div class="col-12 mb-2 custom-control custom-checkbox align-content-center">
<input type="checkbox" class="custom-control-input" name="planimetric_click" id="planimetric_click" value="1" />
<label class="custom-control-label" for="planimetric_click">是否顯示平面圖</label>
</div>
</div>
<div class="form-group col-12" id="build_menu_systemurl_modal_div" name="drawing_extend">
<label class="form-label" for="build_menu_systemurl_modal"><span class="text-danger">*</span>系統圖URL</label>
<input type="text" id="build_menu_systemurl_modal" class="form-control" name="build_menu_systemurl_modal">
</div>
<div class="form-group col-12" id="build_menu_icon_click_onoff_modal_div" name="drawing_extend">
<label class="form-label">昇位圖 - 詳細資料設定</label>
@*<div class="row">
<div class="col">
<input type="radio" name="icon_click_onoff" id="icon_click_on" value="1">
<label for="icon_click_on">
點擊開關
</label>
</div>
<div class="col">
<input type="radio" name="icon_click_onoff" id="icon_click_off" value="0" checked>
<label for="icon_click_off">
彈出視窗
</label>
</div>
</div>*@
<div class="row">
<div class="col" style="display:none">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="icon_click[]" id="icon_click_switch" value="2">
<label class="custom-control-label" for="icon_click_switch">點擊開關</label>
</div>
</div>
<div class="col">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="icon_click[]" id="icon_click_url" value="1">
<label class="custom-control-label" for="icon_click_url">顯示詳細資料</label>
</div>
</div>
</div>
</div>
<div class="form-group col-12" id="build_menu_icon_click_url_modal_div" name="drawing_extend">
<label class="form-label" for="build_menu_icon_click_url_modal">詳細資料 URL</label><br>
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AddTagIntoClickUrl('device_building_tag')">+/[device_building_tag]</button>
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AddTagIntoClickUrl('device_system_tag')">+/[device_system_tag]</button>
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AddTagIntoClickUrl('device_floor_tag')">+/[device_floor_tag]</button>
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AddTagIntoClickUrl('device_name_tag')">+/[device_name_tag]</button>
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AddTagIntoClickUrl('device_serial_tag')">+/[device_serial_tag]</button>
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AddTagIntoClickUrl('tag_name')">+/[tag_name]</button>
<input type="text" id="build_menu_icon_click_url_modal" class="form-control">
</div>
<div class="form-group col-12" id="build_menu_icon_click_url_width_height_modal_div">
<label class="form-label">詳細資料 顯示視窗設定</label><br>
<div class="row">
<div class="col-6 form-group">
<label class="form-label" for="build_menu_icon_click_url_width_modal">寬(單位px)</label>
<input type="number" step="1" id="build_menu_icon_click_url_width_modal" class="form-control">
</div>
<div class="col-6 form-group">
<label class="form-label" for="build_menu_icon_click_url_height_modal">高(單位px)</label>
<input type="number" step="1" id="build_menu_icon_click_url_height_modal" class="form-control">
</div>
</div>
</div>
<div class="form-group col-12" id="build_menu_riser_diagram_url_modal_div" style="display: none">
<label class="form-label" for="build_menu_riser_diagram_url_modal">昇位圖 URL</label><br>
<input type="text" id="build_menu_riser_diagram_url_modal" class="form-control">
</div>
<div class="form-group col-6" id="build_menu_planimetric_floor_modal_div">
<label class="form-label" for="build_menu_planimetric_floor_modal"><span class="text-danger">*</span>平面圖預設樓層</label>
<select class="form-control" id="build_menu_planimetric_floor_modal">
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="SavebuildMenuModal()">儲存</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="menu-floor-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered " role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
樓層 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form id="menu-floor-form">
<div class="row">
<div class="form-group col-6">
<label class="form-label" for="menu_floor_main_modal"><span class="text-danger">*</span>大類</label>
<br>
<span id="menu_floor_main_modal" class="fw-900"></span>
@*<select class="form-control" id="menu_floor_main_modal" disabled>
</select>*@
</div>
<div class="form-group col-6">
<label class="form-label" for="menu_floor_sub_modal"><span class="text-danger">*</span>小類</label>
<br>
<span id="menu_floor_sub_modal" class="fw-900"></span>
@*<select class="form-control" id="menu_floor_sub_modal" disabled>
</select>*@
</div>
<div class="form-group col-12">
<label class="form-label"><span class="text-danger">*</span>可新增樓層</label>
<div class="row ml-2 mr-1" id="floor_check">
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="SaveFloorMenuModal()">儲存</button>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var AllMainList = new Array(0);
var SelectMainList = new Array(0);
var buildMenuTable;
var SelectBuild = "";
var SelectMainSys = "";
var SelectSubSys = "";
var buildMenuFloorTable;
var selectAllMain = false;
$(function () {
$('#floorcard').hide();
GetBuild();
GetMainList();
buildMenuTable = $("#buildMenu_table").DataTable({
"columns": [
{
"data": "building_guid",
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "main_system_guid_name"
},
{
"data": "sub_system_guid_name"
},
{
"data": "drawing_name"
},
{
"data": "planimetric_click_name"
},
{
"data": "icon_click",
"render": function (data, type, row, meta) {
var str = [];
if (2 & parseInt(data) > 0) {
str.push("點擊開關")
}
if (1 & parseInt(data) > 0) {
str.push("顯示詳細資料")
}
return str.join(";");
}
},
{
"data": "icon_click_url"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('bg-guid', data.building_guid);
$(row).attr('ms-guid', data.main_system_guid);
$(row).attr('ss-guid', data.sub_system_guid);
$(row).attr('ms-name', data.main_system_guid_name);
$(row).attr('ss-name', data.sub_system_guid_name);
},
"ajax": {
"url": "/BuildMenu/BuildMenuTable",
"type": "POST",
"data": function (d) {
d.build = SelectBuild,
d.MainList = SelectMainList
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data.data;
if (data == null || data.length == 0) {
this.data = [];
} else {
$.each(this.data, function (k, rel) {
rel.sub_system_guid_name = "<font color='#7c91df'>" + rel.sub_system_guid_name +"</font>"
if (rel.drawing == 2) {
rel.drawing_name = rel.drawing_name + "<br>" + '<a href = "' + rel.system_url +'" target="_blank" >點擊連結</a >'
}
if (rel.drawing == 1) {
rel.drawing_name = rel.drawing_name + "<br>" + '[' + rel.floor_guid_name + ']'
}
})
}
$('#floorcard').hide();
return data;
}
}
});
buildMenuFloorTable = $("#buildMenu_floor_table").DataTable({
"columns": [
{
"data": "sub_system_floor_guid",
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "main_system_guid_name"
},
{
"data": "sub_system_guid_name"
},
{
"data": "floor_guid_name"
},
{
"data": null,
"defaultContent": '<button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('ssf-guid', data.sub_system_floor_guid);
},
"ajax": {
"url": "/BuildMenu/BuildMenuFloorTable",
"type": "POST",
"data": function (d) {
d.build = SelectBuild,
d.main = SelectMainSys,
d.sub = SelectSubSys
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
});
//#region 取棟別
function GetBuild() {
var url = "/BuildMenu/BuildInfoList";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#buildlist').empty();
var buildstr = "";
$.each(rel.data, function (index, val) {
$('#build_menu_building_modal').append($("<option />").val(val.value).text(val.name));
if (index == 0) {
SelectBuild = val.value;
buildstr += '<button type="button" class="btn btn-success waves-effect waves-themed" onclick="SelectBulid(\'' + val.value + '\' ,this)">' + val.name + '</button>';
}
else {
buildstr += '<button type="button" class="btn btn-secondary waves-effect waves-themed" onclick="SelectBulid(\'' + val.value + '\',this)" >' + val.name + '</button>';
}
});
$('#buildlist').append(buildstr);
$('#buildlist').find('.btn-success').trigger('click');
GetMainlistByBuild(SelectBuild);
return;
}
}, 'json');
}
//#endregion
//#region 選擇棟別
function SelectBulid(build, e) {
SelectBuild = build;
if ($("#buildlist").find('.btn').hasClass("btn-success")) {
$("#buildlist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).removeClass("btn-secondary").addClass("btn-success");
$('#menucard').find('.card-title').html(e.innerText + "-選單");
GetMainlistByBuild(SelectBuild);
}
//#endregion
var submain = new Array(0);
//#region 以棟別找系統大類
function GetMainlistByBuild(build) {
var url = "/BuildMenu/MainListBybuild";
var send_data = {
build: build
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#mainlist').empty();
submain = SelectMainList;
SelectMainList = [];
selectAllMain = false;
var mainliststr = "";
AllMainList = [];
$.each(rel.data, function (index, val) {
AllMainList.push(val.value);
mainliststr += '<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2 mr-2" id="btn-' + val.value + '" onclick="SelectMain(\'' + val.value + '\',this)">' + val.name + '</button>';
});
$('#mainlist').append(mainliststr);
if (submain.length != 0) {
$.each(submain, function (ind, va) {
$('#btn-' + va).trigger('click');
});
submain = [];
}
buildMenuTable.ajax.reload();
return;
}
}, 'json');
}
//#endregion
//#region 取所有系統大類
function GetMainList() {
var url = "/BuildMenu/MainList";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#build_menu_main_modal').empty();
$.each(rel.data, function (index, val) {
$('#build_menu_main_modal').append($("<option />").val(val.value).text(val.name));
if (index == 0) {
GetSubList(val.value)
}
});
return;
}
}, 'json');
}
//#endregion
//#region 取大類中的小類(還沒新增)
function GetSubList(main) {
var url = "/BuildMenu/SubListNotAdd";
var send_data = {
main: main,
build: SelectBuild
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#build_menu_sub_modal').empty();
$.each(rel.data, function (index, val) {
$('#build_menu_sub_modal').append($("<option />").val(val.value).text(val.name));
});
return;
}
}, 'json');
}
//#endregion
//#region 選擇系統大類
function SelectMain(main, e) {
if ($(e).hasClass("btn-outline-success")) {
$(e).removeClass("btn-outline-success").addClass("btn-success");
SelectMainList.push(main);
} else if ($(e).hasClass("btn-success")) {
$(e).removeClass("btn-success").addClass("btn-outline-success");
var a = SelectMainList.filter(function (n, i) {
if (n === main) {
SelectMainList.splice(i, 1);
}
});
}
buildMenuTable.ajax.reload();
};
//#endregion
//#region 新增menu
function Addmenu() {
$('.modal-title').html("選單基本資料 - 新增");
$('#build_menu_building_modal').attr('disabled', false);
$('#build_menu_main_modal').attr('disabled', false);
$('#build_menu_sub_modal').attr('disabled', false);
$("#build-menu-form").trigger("reset");
$('#build_menu_building_modal').val(SelectBuild);
$.each($("input[name='icon_click[]']"), function (index, item) {
$(this).prop("checked", false);
});
$('#drawing_4').trigger('change');
GetSubList($('#build_menu_main_modal').val());
GetFloorInSubSystem();
$('#planimetric_click').attr("disabled", false);
$('#build-menu-modal').modal();
}
//#endregion
//#region 修改選擇顯示頁面總類
$('#build_menu_drawing_modal').on("change", $("input[name='drawing']"), function () {
changebuild_menu_drawing_modal();
});
//#endregion
$('#build_menu_icon_click_onoff_modal_div').on("click", "input[type=checkbox]", function () {
if ($(this).prop("checked") && $(this).val() == 1) {
$('#build_menu_icon_click_url_modal_div').show();
$('#build_menu_icon_click_url_width_height_modal_div').show();
} else {
$('#build_menu_icon_click_url_modal_div').hide();
$('#build_menu_icon_click_url_width_height_modal_div').hide();
}
});
//#region 更改大類更換小類
$('#build_menu_main_modal').on("change", function () {
GetSubList($('#build_menu_main_modal').val());
});
//#endregion
//#region 儲存選單
function SavebuildMenuModal() {
if ($('input[name="drawing"]:checked').val() == 2) {
if ($('#build_menu_systemurl_modal').val().length == 0) {
Swal.fire(
{
title: "儲存失敗",
icon: 'warning',
html: '系統圖URL不能為空',
});
return;
}
}
if ($('#build_menu_sub_modal').val() == null) {
Swal.fire(
{
title: "儲存失敗",
icon: 'warning',
html: '沒有小類不能儲存',
});
return;
}
var icon_click = 0;
$.each($("input[name='icon_click[]']"), function (index, item) {
if (item.checked) {
icon_click += parseInt(item.value);
}
});
var url = "/BuildMenu/SavebuildMenuModal";
var send_data = {
building_guid: $('#build_menu_building_modal').val(),
main_system_guid: $('#build_menu_main_modal').val(),
sub_system_guid: $('#build_menu_sub_modal').val(),
drawing: $('input[name="drawing"]:checked').val(),
system_url: $('#build_menu_systemurl_modal').val(),
icon_click: icon_click,
icon_click_url: $('#build_menu_icon_click_url_modal').val(),
icon_click_url_width: $('#build_menu_icon_click_url_width_modal').val(),
icon_click_url_height: $('#build_menu_icon_click_url_height_modal').val(),
planimetric_click: $('input[name="planimetric_click"]:checked').val(),
riser_diagram_url: $('#build_menu_riser_diagram_url_modal').val(),
planimetric_floor_guid: $('#build_menu_planimetric_floor_modal').val()
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
$('#build-menu-modal').modal('hide');
}
else {
buildMenuTable.ajax.reload(null, false);
$('#build-menu-modal').modal('hide');
$('#buildlist').find('.btn-success').trigger('click');
toast_ok(rel.msg);
}
}, 'json');
}
//#endregion
//#region 修改menu
$('#buildMenu_table').on("click", "button.edit-btn", function () {
var url = "/BuildMenu/GetBuildMenu";
var send_data = {
build: $(this).parents('tr').attr('bg-guid'),
main: $(this).parents('tr').attr('ms-guid'),
sub: $(this).parents('tr').attr('ss-guid')
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
}
else {
$('#build_menu_building_modal').val(rel.data.building_guid);
$('#build_menu_main_modal').val(rel.data.main_system_guid);
$('#build_menu_building_modal').attr('disabled', true);
$('#build_menu_main_modal').attr('disabled', true);
$('#build_menu_sub_modal').attr('disabled', true);
$('#build_menu_sub_modal').append($("<option />").val(rel.data.sub_system_guid).text(rel.data.sub_system_guid_name));
$('#build_menu_sub_modal').val(rel.data.sub_system_guid);
$("input[name*='drawing'][value='" + rel.data.drawing + "']").prop("checked", true);
if (rel.data.planimetric_click == 1) {
$('input[name="planimetric_click"]').prop("checked", true)
} else {
$('input[name="planimetric_click"]').prop("checked", false)
}
$('#build_menu_systemurl_modal').val(rel.data.system_url);
$.each($("input[name='icon_click[]']"), function (index, item) {
if (parseInt(item.value) & rel.data.icon_click > 0) {
$(item).prop("checked", true);
} else {
$(item).prop("checked", false);
}
});
@*$("input[name*='icon_click_onoff'][value='" + rel.data.icon_click + "']").prop("checked", true);*@
$('#build_menu_icon_click_url_modal').val(rel.data.icon_click_url);
if (rel.data.icon_click_url_width != undefined && rel.data.icon_click_url_width != null && rel.data.icon_click_url_width > 0) {
$('#build_menu_icon_click_url_width_modal').val(rel.data.icon_click_url_width);
} else {
$('#build_menu_icon_click_url_width_modal').val("");
}
if (rel.data.icon_click_url_height != undefined && rel.data.icon_click_url_height != null && rel.data.icon_click_url_height > 0) {
$('#build_menu_icon_click_url_height_modal').val(rel.data.icon_click_url_height);
} else {
$('#build_menu_icon_click_url_height_modal').val("");
}
changebuild_menu_drawing_modal();
GetFloorInSubSystem(rel.data.planimetric_floor_guid);
$('.modal-title').html("選單基本資料 - 修改");
$('#build-menu-modal').modal();
}
}, 'json');
});
//#endregion
function changebuild_menu_drawing_modal() {
if ($('input[name="drawing"]:checked').val() == 2) {
$('#planimetric_click').attr("disabled", false);
$('#build_menu_icon_click_onoff_modal_div').hide();
$('#build_menu_icon_click_url_modal_div').hide();
$('#build_menu_systemurl_modal_div').show();
@*$('#build_menu_riser_diagram_url_modal_div').hide();*@
$('#build_menu_icon_click_url_width_height_modal_div').hide();
$('#build_menu_planimetric_floor_modal_div').hide();
} else if ($('input[name="drawing"]:checked').val() == 4) {
$('#planimetric_click').attr("disabled", false);
$('#build_menu_systemurl_modal_div').hide();
$('#build_menu_icon_click_onoff_modal_div').show();
if ($("#icon_click_url").prop('checked')) {
$('#build_menu_icon_click_url_modal_div').show();
$('#build_menu_icon_click_url_width_height_modal_div').show();
}
else {
$('#build_menu_icon_click_url_modal_div').hide();
$('#build_menu_icon_click_url_width_height_modal_div').hide();
}
@*$('#build_menu_riser_diagram_url_modal_div').show();*@
$('#build_menu_planimetric_floor_modal_div').hide();
} else if ($('input[name="drawing"]:checked').val() == 1) {
$('#planimetric_click').prop("checked", true).attr("disabled", true);
$('#build_menu_systemurl_modal_div').hide();
$('#build_menu_icon_click_onoff_modal_div').hide();
$('#build_menu_icon_click_url_modal_div').hide();
@*$('#build_menu_riser_diagram_url_modal_div').hide();*@
$('#build_menu_icon_click_url_width_height_modal_div').hide();
$('#build_menu_planimetric_floor_modal_div').show();
}
}
$('#buildMenu_table').on("click", "button.del-btn", function () {
var send_data = {
build: $(this).parents('tr').attr('bg-guid'),
main: $(this).parents('tr').attr('ms-guid'),
sub: $(this).parents('tr').attr('ss-guid')
};
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
if ($("#buildMenu_floor_table").find(".dataTables_empty").length != 1) {
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: '下方樓層設定中尚有樓層正在使用該棟別選單,故無法刪除',
html: '需先刪除所有相關樓層才可進行刪除',
});
return;
}
else {
var url = "/BuildMenu/DeleteBuildMenu/";
$.post(url, send_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
buildMenuTable.ajax.reload(null, false);
}, 'json');
}
}
});
});
$('#buildMenu_table').on("click", "tbody>tr", function () {
$(this).parents().find('tr').css('background-color', '#fff');
$(this).css('background-color', '#67B4AC');
SelectBuild = $(this).attr('bg-guid');
SelectMainSys = $(this).attr('ms-guid');
SelectSubSys = $(this).attr('ss-guid');
@*$('#menu_floor_main_modal').append($("<option />").val($(this).attr('ms-guid')).text($(this).attr('ms-name')));
$('#menu_floor_sub_modal').append($("<option />").val($(this).attr('ss-guid')).text($(this).attr('ss-name')));*@
$('#menu_floor_main_modal').html($(this).attr('ms-name'))
$('#menu_floor_sub_modal').html($(this).attr('ss-name'))
$('#floorcard').show();
$('#floorcard').find('.card-title').html($(this).attr('ms-name') + "-" + $(this).attr('ss-name') + "-樓層設定");
buildMenuFloorTable.ajax.reload(null, false);
});
function AddFloor() {
var send_data = {
build: SelectBuild,
main: SelectMainSys,
sub: SelectSubSys
};
var url = "/BuildMenu/GetNotUsefloor/";
$.post(url, send_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
var checkbox = "";
$('#floor_check').empty();
$.each(rel.data, function (index, val) {
checkbox += '<div class="col-3 mb-2 custom-control custom-checkbox align-content-center">';
checkbox += '<input type="checkbox" class="custom-control-input" name="selectfloor[]" id="' + val.value + '" value="' + val.value + ' " />';
checkbox += '<label class="custom-control-label" for="' + val.value + '">' + val.name + '</label>';
checkbox += '</div>';
});
$('#floor_check').append(checkbox);
$('#menu-floor-modal').modal();
buildMenuFloorTable.ajax.reload(null, false);
}, 'json');
}
function SaveFloorMenuModal() {
var SelectAddFloor = $("input[name='selectfloor[]']:checked").map(function () {
return $(this).val();
}).get();
if (SelectAddFloor.length == 0) {
Swal.fire(
{
title: "儲存失敗",
icon: 'warning',
html: '沒有選擇樓層不能儲存',
});
return;
}
var send_data = {
build: SelectBuild,
main: SelectMainSys,
sub: SelectSubSys,
floorlist: SelectAddFloor
};
var url = "/BuildMenu/SaveAddsubfloor/";
$.post(url, send_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
buildMenuFloorTable.ajax.reload(null, false);
$('#menu-floor-modal').modal('hide');
}, 'json');
}
$('#buildMenu_floor_table').on("click", "button.del-btn", function () {
var send_data = {
subfloorguid: $(this).parents('tr').attr('ssf-guid')
};
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/BuildMenu/DeleteBuildFloorMenu/";
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else if (rel.code == "9997") {
var htnl = rel.msg + "<br>"
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: htnl,
});
}
else {
toast_warning(rel.msg);
}
return;
}
else {
toast_ok(rel.msg);
buildMenuFloorTable.ajax.reload(null, false);
return;
}
}, 'json');
}
});
});
function AllMainSys() {
if (selectAllMain) {
SelectMainList = [];
$('#mainlist').find('.btn').removeClass('btn-success').addClass("btn-outline-success");
selectAllMain = false;
} else {
SelectMainList = AllMainList;
$('#mainlist').find('.btn').removeClass('btn-outline-success').addClass("btn-success");
selectAllMain = true;
}
buildMenuTable.ajax.reload();
}
function AddTagIntoClickUrl(tag) {
var a = $('#build_menu_icon_click_url_modal').val();
switch (tag) {
case 'device_building_tag':
$('#build_menu_icon_click_url_modal').val(a + '/[device_building_tag]');
break;
case 'device_system_tag':
$('#build_menu_icon_click_url_modal').val(a + '/[device_system_tag]');
break;
case 'device_floor_tag':
$('#build_menu_icon_click_url_modal').val(a + '/[device_floor_tag]');
break;
case 'device_name_tag':
$('#build_menu_icon_click_url_modal').val(a + '/[device_name_tag]');
break;
case 'device_serial_tag':
$('#build_menu_icon_click_url_modal').val(a + '/[device_serial_tag]');
break;
case 'tag_name':
$('#build_menu_icon_click_url_modal').val(a + '/[tag_name]');
break;
}
}
function GetFloorInSubSystem(floor = null) {
var url = "/BuildMenu/GetFloorInSubSystem";
var send_data = {
build: $('#build_menu_building_modal').val(),
main: $('#build_menu_main_modal').val(),
sub: $('#build_menu_sub_modal').val(),
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
}
else {
if (rel.data.length == 0) {
$('#drawing_1_div').hide();
$('#build_menu_planimetric_floor_modal_div').hide();
}
else {
$('#build_menu_planimetric_floor_modal').empty();
$.each(rel.data, function (index, val) {
$('#build_menu_planimetric_floor_modal').append($("<option />").val(val.value).text(val.name));
});
if (floor != null) {
$('#build_menu_planimetric_floor_modal').val(floor);
}
$('#drawing_1_div').show();
$('#build_menu_planimetric_floor_modal_div').show();
changebuild_menu_drawing_modal();
}
}
}, 'json');
}
</script>
}

View File

@ -0,0 +1,537 @@
@{
ViewData["MainNum"] = "2";
ViewData["SubNum"] = "1";
ViewData["Title"] = "設備資料匯入";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">首頁</a></li>
<li class="breadcrumb-item">設備管理</li>
<li class="breadcrumb-item active">設備資料匯入</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-xl-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<ul class="nav nav-tabs" id="tabs" role="tablist">
<li class="nav-item"><a class="nav-link active" data-toggle="tab" href="#tab-import" role="tab"><span class="hidden-sm-down">資料匯入</span></a></li>
<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#tab-check" role="tab"><span class="hidden-sm-down">資料檢核</span></a></li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane fade show active" id="tab-import" role="tabpanel" aria-labelledby="tab-import">
@Html.Partial("_RawDataImport")
</div>
<div class="tab-pane fade" id="tab-check" role="tabpanel" aria-labelledby="tab-check">
@Html.Partial("_RawDataCheck")
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var rawDataImportTable, rawDataCheckTable;
var deviceCheckFilterList;
var selectedDeviceCheckFilter = {};
//#region 資料匯入分頁
//#region 資料匯入 document ready
$(function () {
//#region 資料匯入 DataTable
rawDataImportTable = $("#rawDataImport_table").DataTable({
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "device_number"
},
{
"data": "device_result"
},
{
"data": "created_at"
},
],
//"order": [[2, "desc"]],
"ajax": {
"url": "/DeviceImport/RawDataList",
"type": "POST",
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
//#endregion
});
//#endregion
//#region 資料匯入驗證
var ImportFileValidate = $("#import-file-form").validate({
rules: {
import_file_input: {
accept: ".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
},
}
});
//#endregion
//#region 上傳設備檔案
function preImportRawDataFile() {
var input_file = document.getElementById('import_file_input');
input_file.outerHTML = input_file.outerHTML;
$('#import_file_input').click();
}
function importRawDataFile() {
import_files = $('#import_file_input')[0].files;
if (import_files.length <= 0) {
return;
}
if ($("#import-file-form").valid()) {
Swal.fire(
{
title: "設備檔案匯入",
text: "匯入檔案會將舊有資料完全移除,你確定是否要匯入?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/DeviceImport/ImportRawDataFile";
var formData = new FormData();
if (import_files.length > 0) {
Array.from(import_files).forEach(function (item, index) {
formData.append("import_files", item)
});
}
$("#import-file-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
rawDataImportTable.clear().draw();
$.ajax({
type: "POST",
url: url,
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
rawDataImportTable.ajax.reload(null, false);
}
$("#import-file-btn").html('<span class="fal fa-plus mr-1"></span>設備檔案匯入').attr("disabled", false);
return;
}
else {
toast_ok(rel.msg);
$("#import-file-btn").html('<span class="fal fa-plus mr-1"></span>設備檔案匯入').attr("disabled", false);
rawDataImportTable.ajax.reload(null, false);
GetRawDataCheckFilter();
return;
}
},
});
}
});
}
}
//#endregion
//#endregion
//#region 資料檢核分頁
//#region 資料檢核 document ready
$(function () {
//預設載入上方選單列表
GetRawDataCheckFilter();
//#region 資料檢核 DataTable
rawDataCheckTable = $("#rawDataCheck_table").DataTable({
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "check_temp_device_number",
"createdCell": function (td, cellData, rowData, row, col) {
if (rowData && rowData.compare_device_number != 0) {
$(td).css('color', 'red');
}
},
},
{
"data": "check_temp_device_system_category_layer3_key",
"createdCell": function (td, cellData, rowData, row, col) {
if (rowData && rowData.compare_system_category_layer3 != 0) {
$(td).css('color', 'red');
}
},
"render": function (data, type, row, meta) {
if (row) {
var value = row.check_temp_device_system_category_layer3 ? row.check_temp_device_system_category_layer3 : "";
var key = row.check_temp_device_system_category_layer3_key ? row.check_temp_device_system_category_layer3_key : "";
return value + " " + key
}
}
},
{
"data": "check_temp_disaster_key",
"createdCell": function (td, cellData, rowData, row, col) {
if (rowData && rowData.compare_device_disaster != 0) {
$(td).css('color', 'red');
}
},
"render": function (data, type, row, meta) {
if (row) {
var key = row.check_temp_disaster_key ? row.check_temp_disaster_key : "";
return key;
}
else {
return '';
}
}
},
{
"data": "device_number",
"createdCell": function (td, cellData, rowData, row, col) {
if (rowData && rowData.compare_device_number != 0) {
$(td).css('color', 'red');
}
},
},
{
"data": "device_system_category_layer3_key",
"createdCell": function (td, cellData, rowData, row, col) {
if (rowData && rowData.compare_system_category_layer3 != 0) {
$(td).css('color', 'red');
}
},
"render": function (data, type, row, meta) {
if (row) {
var value = row.device_system_category_layer3 ? row.device_system_category_layer3 : "";
var key = row.device_system_category_layer3_key ? row.device_system_category_layer3_key : "";
return value + " " + key
}
}
},
{
"data": "device_disaster_type_text",
"createdCell": function (td, cellData, rowData, row, col) {
if (rowData && rowData.compare_device_disaster != 0) {
$(td).css('color', 'red');
}
},
},
{
"data": "device_coordinate"
},
],
//"order": [[2, "desc"]],
"ajax": {
"url": "/DeviceImport/DeviceCheckTableList",
"type": "POST",
"data": function (d) {
d.Building_tag = selectedDeviceCheckFilter.building_tag ? selectedDeviceCheckFilter.building_tag : "";
d.System_tag = selectedDeviceCheckFilter.system_tag ? selectedDeviceCheckFilter.system_tag : "";
d.System_category = selectedDeviceCheckFilter.system_category ? selectedDeviceCheckFilter.system_category : "";
d.Abnormal = selectedDeviceCheckFilter.abnormal ? selectedDeviceCheckFilter.abnormal : "all";
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
$("#abnormal-amount").html(rel.data.deviceCheckAmount)
if (rel.data.deviceCheckAmount == 0) {
$("#btn-replace").prop("disabled", false);
} else {
$("#btn-replace").prop("disabled", true);
}
data = rel.data.deviceCheckTableList;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
//#endregion 資料檢核 DataTable
});
//#endregion 資料檢核 document ready
//#region 取得上方搜尋過濾選單
function GetRawDataCheckFilter() {
var url = "/DeviceImport/GetRawDataCheckFilter";
$.post(url, null, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
console.log(rel.data);
deviceCheckFilterList = rel.data;
$("#building-tag-list").empty();
var html = '';
deviceCheckFilterList.forEach(function (building_tag_item, building_tag_index) {
html += `
<div class="btn-group mr-2 btn-building-tag-group">
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2 btn-building-tag" data-building-tag="${building_tag_item.building_tag}" onclick="ChangeDeviceCheckFilterPanel('${building_tag_item.building_tag}')">${building_tag_item.building_tag}</button>
<button type="button" class="btn btn-secondary mb-2 btn-building-tag" data-building-tag="${building_tag_item.building_tag}" onclick="return false;">${building_tag_item.building_amount}</button>
</div>
`;
});
$('#building-tag-list').append(html);
$('#building-tag-list > .btn-building-tag-group').first().children().first().trigger('click');
return;
}
}, 'json');
}
//#endregion 取得上方搜尋過濾選單
function ChangeDeviceCheckFilterPanel(building_tag, system_tag = "", system_category = "") {
if (building_tag == undefined && building_tag == null || building_tag == "") {
toast_warning("請先選擇區域");
return;
}
if ($(".btn-building-tag").hasClass("btn-success")) {
$(".btn-building-tag").removeClass("btn-success").addClass("btn-secondary");
}
$(".btn-building-tag").each(function (index, item) {
var tag = $(item).attr("data-building-tag");
if (tag == building_tag) {
$(item).removeClass("btn-secondary").addClass("btn-success");
}
});
//選擇的棟別
selectedDeviceCheckFilter.building_tag = building_tag;
//系統別 全選
$('#system-tag-all-warp').empty()
if ("all" == system_tag) {
$('#system-tag-all-warp').append(`<button type="button" class="btn btn-success waves-effect waves-theme mb-2" id="btn-system-tag-all" onclick="ChangeDeviceCheckFilterPanel('${building_tag}', 'all')">全選</button>`);
selectedDeviceCheckFilter.system_tag = system_tag;
} else {
$('#system-tag-all-warp').append(`<button type="button" class="btn btn-secondary waves-effect waves-theme mb-2" id="btn-system-tag-all" onclick="ChangeDeviceCheckFilterPanel('${building_tag}', 'all')">全選</button>`);
}
//系統別 個別選單
$('#system-tag-list').empty();
deviceCheckFilterList.forEach(function (building_item, building_item_index) {
if (building_item.building_tag == building_tag) {
var system_html = '';
building_item.system_tags.forEach(function (system_item, system_item_index) {
if (system_item.system_tag == system_tag && "all" != system_tag) {
system_html += `<button type="button" class="btn btn-success waves-effect waves-themed mr-2 mb-2" onclick="ChangeDeviceCheckFilterPanel('${building_item.building_tag}', '${system_item.system_tag}')">${system_item.system_tag}</button>`
//選擇的系統別
selectedDeviceCheckFilter.system_tag = system_tag;
}
else {
system_html += `<button type="button" class="btn btn-secondary waves-effect waves-themed mr-2 mb-2" onclick="ChangeDeviceCheckFilterPanel('${building_item.building_tag}', '${system_item.system_tag}')">${system_item.system_tag}</button>`
}
});
$('#system-tag-list').append(system_html);
if (system_tag == '') {
$('#system-tag-list').children().first().trigger('click');
return;
} else {
//設備分類 全選
$('#system-category-all-warp').empty()
if ("all" == system_category) {
$('#system-category-all-warp').append(`<button type="button" class="btn btn-success waves-effect waves-theme mb-2" id="btn-system-category-all" onclick="ChangeDeviceCheckFilterPanel('${building_tag}', '${system_tag}', 'all')">全選</button>`);
selectedDeviceCheckFilter.system_category = system_category;
} else {
$('#system-category-all-warp').append(`<button type="button" class="btn btn-secondary waves-effect waves-theme mb-2" id="btn-system-category-all" onclick="ChangeDeviceCheckFilterPanel('${building_tag}', '${system_tag}', 'all')">全選</button>`);
}
$('#system-category-list').empty();
building_item.system_tags.forEach(function (system_item, system_item_index) {
if (system_item.system_tag == system_tag) {
var system_category_html = '';
system_item.system_categories.forEach(function (system_category_item, system_category_item_index) {
if (system_category_item == system_category && "all" != system_category) {
system_category_html += `<button type="button" class="btn btn-success waves-effect waves-themed mr-2 mb-2" onclick="ChangeDeviceCheckFilterPanel('${building_item.building_tag}', '${system_item.system_tag}', '${system_category_item}')">${system_category_item}</button>`
//選擇的設備種類
selectedDeviceCheckFilter.system_category = system_category;
}
else {
system_category_html += `<button type="button" class="btn btn-secondary waves-effect waves-themed mr-2 mb-2" onclick="ChangeDeviceCheckFilterPanel('${building_item.building_tag}', '${system_item.system_tag}', '${system_category_item}')">${system_category_item}</button>`
}
});
$('#system-category-list').append(system_category_html);
} else if ("all" == system_tag) { //系統別 為全選的時候
var system_category_html = '';
system_item.system_categories.forEach(function (system_category_item, system_category_item_index) {
if (system_category_item == system_category && "all" != system_category) {
system_category_html += `<button type="button" class="btn btn-success waves-effect waves-themed mr-2 mb-2" onclick="ChangeDeviceCheckFilterPanel('${building_item.building_tag}', '${system_tag}', '${system_category_item}')">${system_category_item}</button>`
//選擇的設備種類
selectedDeviceCheckFilter.system_category = system_category;
}
else {
system_category_html += `<button type="button" class="btn btn-secondary waves-effect waves-themed mr-2 mb-2" onclick="ChangeDeviceCheckFilterPanel('${building_item.building_tag}', '${system_tag}', '${system_category_item}')">${system_category_item}</button>`
}
});
$('#system-category-list').append(system_category_html);
}
});
if (system_category == '') {
$('#system-category-list').children().first().trigger('click');
return;
}
else {
//預設異常分類全選
if (selectedDeviceCheckFilter.abnormal == undefined || selectedDeviceCheckFilter.abnormal == "") {
ChangeRawDeviceCheckTable(3, "all")
}
}
}
}
});
}
function ChangeRawDeviceCheckTable(target_filter, abnormal = "all") {
switch (target_filter) {
case 1: //系統別
selectedDeviceCheckFilter.system_tag = "all";
break;
case 2: //設備分類
selectedDeviceCheckFilter.system_category = "all";
break;
case 3: //異常分類
selectedDeviceCheckFilter.abnormal = abnormal;
if ("abnormal" == abnormal) {
ChangeDeviceCheckFilterPanel(selectedDeviceCheckFilter.building_tag, "all", "all")
}
if ($(".btn-abnormal-tag").hasClass("btn-success")) {
$(".btn-abnormal-tag").removeClass("btn-success").addClass("btn-secondary");
}
$(".btn-abnormal-tag").each(function (index, item) {
var tag = $(item).attr("data-abnormal-tag");
if (tag == abnormal) {
$(item).removeClass("btn-secondary").addClass("btn-success");
}
});
break;
}
if ($('#btn-check').attr('data-auto-first') == "true") {
//第一次自動點擊檢核
$('#btn-check').attr('data-auto-first', "false");
rawDataCheckTable.ajax.reload(null, false);
}
}
//#region 重整資料檢核表
function ReloadRawDataCheckTable() {
rawDataCheckTable.ajax.reload(null, false);
}
//#endregion重整資料檢核表
//#region 資料取代
function DataCheckReplace() {
Swal.fire(
{
title: "資料取代",
text: "資料將會取代當前設備資訊,確定是否要取代?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/DeviceImport/DeviceCheckReplace";
$.post(url, selectedDeviceCheckFilter, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
toast_ok(rel.msg);
ReloadRawDataCheckTable();
}
}, 'json');
}
});
}
//#endregion 資料取代
//#endregion 資料檢核分頁
</script>
}

View File

@ -0,0 +1,64 @@
<div class="row mb-3">
<div class="col-12 row align-items-center px-3 justify-content-between">
<span class="col-1">區域</span>
<div class="col-11 row">
<div id="building-tag-list" class="col-12"></div>
</div>
</div>
<div class="col-12 row align-items-center px-3 justify-content-between">
<span class="col-1">系統別</span>
<div class="col-11 row align-items-start">
<div class="col-1" id="system-tag-all-warp">
</div>
<div id="system-tag-list" class="col-11">
</div>
</div>
</div>
<div class="col-12 row align-items-center px-3 justify-content-between">
<span class="col-1">設備分類</span>
<div class="col-11 row align-items-start">
<div class="col-1" id="system-category-all-warp">
</div>
<div id="system-category-list" class="col-11">
</div>
</div>
</div>
<div class="col-12 row align-items-center px-3 justify-content-between">
<span class="col-1">異常分類</span>
<div id="abnormal-list" class="col-11 row align-items-center">
<div class="col-1">
<button type="button" class="btn btn-success waves-effect waves-theme btn-abnormal-tag" data-abnormal-tag="all" onclick="ChangeRawDeviceCheckTable(3, 'all')">全選</button>
</div>
<div class="col-11">
<div class="btn-group mr-2 btn-building-tag-group">
<button type="button" class="btn btn-secondary waves-effect waves-themed btn-abnormal-tag" data-abnormal-tag="abnormal" onclick="ChangeRawDeviceCheckTable(3, 'abnormal')">異常資料</button>
<button type="button" class="btn btn-secondary btn-abnormal-tag" id="abnormal-amount" data-abnormal-tag="abnormal" onclick="return false;">99999</button>
</div>
<button type="button" class="btn btn-primary mr-2 waves-effect waves-themed " id="btn-check" onclick="ReloadRawDataCheckTable()" data-auto-first="true">資料檢核</button>
<button type="button" class="btn btn-primary mr-2 waves-effect waves-themed " id="btn-replace" onclick="DataCheckReplace()">資料取代</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="rawDataCheck_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>設備編號(匯入資料)</th>
<th>設備類別(匯入資料)</th>
<th>防災類別(匯入資料)</th>
<th>設備編號(現有資料)</th>
<th>設備類別(現有資料)</th>
<th>防災類別(現有資料)</th>
<th>地圖坐標(現有資料)</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>

View File

@ -0,0 +1,26 @@
<div class="row mb-3">
<div class="col-12 d-flex justify-content-end">
<form id="import-file-form">
<input id="import_file_input" type="file" name="import_file_input" onchange="importRawDataFile()" style="display:none" multiple accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />
<button type="button" class="btn btn-success waves-effect waves-themed mb-3" id="import-file-btn" onclick="preImportRawDataFile()"><span class="fal fa-plus mr-1"></span>設備檔案匯入</button>
</form>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="rawDataImport_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>設備編號</th>
<th>匯入結果</th>
<th>匯入時間</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,279 @@
@{
ViewData["MainNum"] = "4";
ViewData["SubNum"] = "2";
ViewData["Title"] = "聯絡清單";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">首頁</a></li>
<li class="breadcrumb-item active">聯絡清單</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<div class="subheader">
<h1 class="subheader-title">
<span>聯絡清單</span>
</h1>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<div class="btn-group btn-group-md" id="Disasterlist">
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3">
<div class="pr-3 ">
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" @*style="border: 1px dashed;"*@ onclick="Allgroupingselect()">全選</button>
</div>
<div class="pr-3 row col">
<div class="frame-wrap" id="groupinglist">
</div>
</div>
<div class="card border mb-g w-100 mb-5" id="emergency_setting_card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-between">
<div class="card-title font-weight-bold">聯絡清單</div>
<div class="text-right ">
<a href="javascript:;" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" onclick="ExportPDF()">匯出PDF</a>
<a href="javascript:;" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" onclick="ExportExcel()">匯出Excel</a>
</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="emergency_contact_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>組別</th>
<th>姓名</th>
<th>部門</th>
<th>電話</th>
<th>LINE ID</th>
<th>電子信箱</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var Selectadisaster;
var selectgroupidlist = new Array(0);
var Allgroupidlist = new Array(0);
var Allgroupingbool = false;
var EmergencyContact;
$(function () {
EmergencyContact = $("#emergency_contact_table").DataTable({
"columns": [
{
"data": "groupingName",
},
{
"data": "full_name"
},
{
"data": "departmentName"
},
{
"data": "phone"
},
{
"data": "lineid"
},
{
"data": "email"
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('guid', data.emergency_guid);
},
"ajax": {
"url": "/EmergencyContact/EmergencyContactTable",
"type": "POST",
"data": function (d) {
d.selectgroupidlist = selectgroupidlist
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
GetDisasterList();
})
//取得災難類別
function GetDisasterList() {
var url = "/EmergencySetting/DisasterList";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#Disasterlist').empty();
var Disasterstr = "";
$.each(rel.data, function (index, val) {
if (index == 0) {
Disasterstr += '<button type="button" class="btn btn-success waves-effect waves-themed" onclick = "SelectDisaster(' + val.value + ',this)"> ' + val.name + '</button>';
}
else {
Disasterstr += '<button type="button" class="btn btn-secondary waves-effect waves-themed" onclick = "SelectDisaster(' + val.value + ',this)">' + val.name + '</button>';
}
});
$('#Disasterlist').append(Disasterstr);
$('#Disasterlist').find('.btn-success').trigger('click');
return;
}
}, 'json');
}
//選擇災難類別
function SelectDisaster(Disaster, e) {
Selectadisaster = Disaster;
if ($("#Disasterlist").find('.btn').hasClass("btn-success")) {
$("#Disasterlist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).removeClass("btn-secondary").addClass("btn-success");
GetGroupingList();
Allgroupingbool = false;
selectgroupidlist = [];
//selectsetting = 0;
EmergencyContact.ajax.reload();
}
//取得編組列表
function GetGroupingList() {
var url = "/EmergencyGrouping/GetGroupingList";
var send_data = {
system_parent_id: Selectadisaster
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
var grouping = "";
$('#groupinglist').empty();
Allgroupidlist = [];
$.each(rel.data, function (index, val) {
Allgroupidlist.push(val.id);
grouping += '<div class="btn-group mb-2 mr-2" grouping = "' + val.id + '">';
grouping += '<button type="button" class="btn btn-outline-success select" onclick="SelectGrouping(' + val.id + ',this)">' + val.name + '</button>';
grouping += '</div>';
});
$('#groupinglist').append(grouping);
return;
}
}, 'json');
}
//選擇組別
function SelectGrouping(grouping, e)
{
if ($(e).hasClass("btn-outline-success")) {
$(e).removeClass("btn-outline-success").addClass("btn-success");
selectgroupidlist.push(grouping);
} else if ($(e).hasClass("btn-success")) {
$(e).removeClass("btn-success").addClass("btn-outline-success");
var a = selectgroupidlist.filter(function (n, i) {
if (n === grouping) {
selectgroupidlist.splice(i, 1);
}
});
}
EmergencyContact.ajax.reload();
}
//全選所有組別
function Allgroupingselect()
{
if (Allgroupingbool) {
$('#groupinglist').find(".btn-success").removeClass("btn-success").addClass("btn-outline-success");
selectgroupidlist = [];
Allgroupingbool = false;
}
else {
$('#groupinglist').find(".btn-outline-success").removeClass("btn-outline-success").addClass("btn-success");
selectgroupidlist = Allgroupidlist;
Allgroupingbool = true;
}
EmergencyContact.ajax.reload();
}
//匯出pdf
function ExportPDF() {
if (selectgroupidlist.length == 0) {
Swal.fire(
{
title: "PDF匯出失敗",
icon: 'warning',
html: '請先選擇組別',
});
return;
} else {
var send_data =
{
disaster: $('#Disasterlist').find('.btn-success').html(),
groupidlist: selectgroupidlist
}
window.location = "/EmergencyContact/ExportPDF?post=" + JSON.stringify(send_data);
}
}
//匯出Excel
function ExportExcel() {
if (selectgroupidlist.length == 0) {
Swal.fire(
{
title: "Excel匯出失敗",
icon: 'warning',
html: '請先選擇組別',
});
return;
} else {
var send_data =
{
disaster: $('#Disasterlist').find('.btn-success').html(),
groupidlist: selectgroupidlist
}
window.location = "/EmergencyContact/ExportExcel?post=" + JSON.stringify(send_data);
}
}
</script>
}

View File

@ -0,0 +1,86 @@
@{
ViewData["MainNum"] = "4";
ViewData["SubNum"] = "1";
ViewData["Title"] = "設備總覽";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">首頁</a></li>
<li class="breadcrumb-item active">設備總覽</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-xl-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<ul class="nav nav-tabs" id="tabs" role="tablist">
<li class="nav-item"><a class="nav-link active" data-toggle="tab" href="#tab-alarm-device" role="tab"><span class="hidden-sm-down ml-1">報警設備</span></a></li>
<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#tab-emergency-device" role="tab"><span class="hidden-sm-down ml-1">緊急應變設備</span></a></li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane fade show active" id="tab-alarm-device" role="tabpanel" aria-labelledby="tab-build-info">
@Html.Partial("_AlarmDevice")
</div>
<div class="tab-pane fade" id="tab-emergency-device" role="tabpanel" aria-labelledby="tab-build-floor">
@Html.Partial("_EmergencyDevice")
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var AlarmDeviceTable, EmergencyDeviceTable;
//#region 報警設備 document ready
$(function () {
});
//#endregion
</script>
<script>
//#region 緊急應變設備 document ready
$(function () {
//#region 取得防災類別
var url = "/EmergencyDeviceMenu/GetDisaster/";
$.post(url, null, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
$("#disaster").empty();
var html = "";
rel.data.forEach(function (item, index) {
if (index == 0) {
html += '<button type="button" class="btn btn-success ml-2" onclick="SelectDisaster(' + item.value + ',this)">' + item.name + '</button>';
}
else {
html += '<button type="button" class="btn btn-secondary ml-2" onclick="SelectDisaster(' + item.value + ',this)">' + item.name + '</button>';
}
});
html += '<button type="button" class="btn btn-secondary ml-auto" onclick="OnSimulationExercise(``,1)">' + '模擬演練' + '</button>';
$('#disaster').append(html);
$('#disaster').find('.btn-success').click();
}
}, 'json');
});
//#endregion
</script>
}

View File

@ -0,0 +1 @@


View File

@ -0,0 +1,195 @@
<div class="page-main">
@*<div class="main-header">
<h1 class="main-title" id="mainTitle"></h1>
</div>*@
<div id="pageContent">
<div class="panel">
<div class="panel-hdr">
<div class="col-auto">防災類別</div>
<div class="col" id="disaster"></div>
<h2 class="py-2" >
防災類別
</h2>
</div>
<div class="panel-hdr">
<h2 class="py-2" id="building">
</h2>
</div>
<div class="panel-hdr">
<h2 class="py-2" id="floors">
</h2>
</div>
<div class="panel-hdr">
<h2 class="py-2" id="system">
設備大類
<!-- <button type="button" class="btn btn-success ml-2" onclick="GetAlarm(false,this)">全選</button> -->
</h2>
</div>
<div class="panel-hdr">
<h2 class="py-2" id="layer3">
設備小類
</h2>
</div>
<div class="panel-container">
<div class="panel-content">
<div class="frame-wrap">
<div class="row">
<div class="col-6">
<div id="datatablediv">
<table class="table table-bordered table-hover m-0 text-center" id="Device_menu_table">
<thead class="thead-themed">
<tr>
<th>設備編號</th>
<th>設備類別</th>
<th>樓層</th>
<th>異常時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="col-6" id="iframe-floormap">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal modal-fullscreen example-modal-fullscreen" id="SimulationExercisemodal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content h-100 border-0 shadow-0 bg-fusion-800">
<button type="button" class=" position-absolute pos-right mr-sm-3 mt-sm-3 z-index-space btn btn-danger waves-effect waves-themed" disabled id="closemodal" onclick="Closemodal()">關閉流程</button>
<div class="modal-body bg-white">
<div class="container-fluid">
<div class="row">
<div class="col-12 text-center"><h1 class="mb-3">緊急應變措施</h1></div>
<ul class="nav nav-tabs mb-3 w-100" role="tablist" id="bigsetting">
<li class="nav-item"> <a class="nav-link fs-xl py-3 px-5" data-toggle="tab" href="#" role="tab"> <i class="fal fa-check text-success"></i> <span class="hidden-sm-down ml-1 text-secondary">確認與通報</span> </a> </li>
<li class="nav-item"> <a class="nav-link fs-xl py-3 px-5" data-toggle="tab" href="#" role="tab"> <i class="fal fa-check text-success"></i> <span class="hidden-sm-down ml-1 text-secondary">通報火災授信總機</span> </a> </li>
<li class="nav-item"> <a class="nav-link fs-xl py-3 px-5" data-toggle="tab" href="#" role="tab"> <i class="fal fa-check text-success"></i> <span class="hidden-sm-down ml-1 text-secondary">通報防災中心</span> </a> </li>
<li class="nav-item"> <a class="nav-link fs-xl py-3 px-5" data-toggle="tab" href="#" role="tab"> <i class="fal fa-check text-success"></i> <span class="hidden-sm-down ml-1 text-secondary">疏導人群</span> </a> </li>
</ul>
</div>
<div class="row">
<div class="col-md-8 tab-content" id="small_setting">
<div class="tab-pane fade show active" id="export_modal" role="tabpanel" aria-labelledby="16_modal">
<div class="row">
<div class="pr-2" style="width:38.5%">
<div id="panel-1" class="panel">
<div class="panel-container show">
<div class="panel-content">
<ul class="list-group">
<li class="list-group-item active"> <i class="fal fa-check text-success"></i> 確認與通報</li>
<li class="list-group-item"> <i class="fal fa-check text-success"></i> 通報火災授信總機</li>
<li class="list-group-item"> <i class="fal fa-check text-success"></i> 通報防災中心</li>
<li class="list-group-item"> <i class="fal fa-check text-success"></i> 疏導人群</li>
</ul>
</div>
</div>
</div>
</div>
<div class="" style="width:61.5%">
<div id="panel-2" class="panel">
<div class="panel-hdr">
<h2>通報火災授信總機</h2>
</div>
<div class="panel-container show">
<div class="panel-content">
<div class="panel-tag">
All panels needs to have an unique ID in order to use the panel funtions. <code>.panel</code> is a container with no padding, <code>.panel-hdr</code> has a <code>min-height</code> value and default <code>flexbox</code> properties. The <code>.panel-toolbar</code> is inserted into <code>.panel-hdr</code> for extra elements. The <code>.panel-container</code> wraps <code>.panel-content</code> which has a predefined padding.
</div>
<p>
Default panel text.
</p>
</div>
<div class="panel-content py-2 border-faded border-left-0 border-right-0 border-bottom-0 text-muted d-flex justify-content-between">
<div class=""><button type="button" class="btn btn-danger waves-effect waves-themed mr-2"> 不通報 </button><input type="text" class=""></div>
<div><button type="button" class="btn btn-success waves-effect waves-themed"> 下一步 </button></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div id="panel-12" class="panel">
<div class="panel-hdr border-faded border-top-0 border-right-0 border-left-0 shadow-0">
<h2></h2>
<div class="panel-toolbar pr-3 align-self-end">
<ul id="demo_panel-tabs" class="nav nav-tabs border-bottom-0 nav-tabs-clean" role="tablist">
<li class="nav-item">
<a class="nav-link text-dark active" data-toggle="tab" href="#tab_content" role="tab">緊急聯絡清單</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" data-toggle="tab" href="#tab_dohistory" role="tab">操作歷史</a>
</li>
</ul>
</div>
</div>
<div class="panel-container show">
<div class="panel-content tab-content">
<div class="tab-pane fade show active" id="tab_content" role="tabpanel" aria-labelledby="tab_content">
<div>
組別
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2 allbtn" onclick="Allgroupingselect()"> 全選 </button>
</div>
<h2 id="button_grouping">
<button type="button" class="btn btn-success waves-effect waves-themed mb-2"> 主防災中心 </button>
<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2"> 通報聯絡班 </button>
<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2"> 外部救援引導班 </button>
<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2"> 滅火班 </button>
<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2"> 緊急救護班 </button>
<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2"> 安全防護班 </button>
</h2>
<div id="membertablediv">
<table class="table table-bordered m-0" id="membertable">
<thead>
<tr>
<th>姓名</th>
<th>部門</th>
<th>電話</th>
<th>LineID</th>
<th>Email</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="tab-pane fade" id="tab_dohistory" role="tabpanel" aria-labelledby="tab_dohistory">
<div id="dohistorytablediv">
<table class="table table-bordered m-0" id="dohistorytable">
<thead>
<tr>
<th>項目</th>
<th>步驟</th>
<th>結果</th>
<th>時間</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,568 @@
@{
ViewData["MainNum"] = "3";
ViewData["SubNum"] = "2";
ViewData["Title"] = "人員編組設定";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">首頁</a></li>
<li class="breadcrumb-item active">人員編組設定</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<div class="subheader">
<h1 class="subheader-title">
<span>人員編組設定</span>
</h1>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<div class="btn-group btn-group-md" id="Disasterlist">
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3">
<div class="pr-3 ">
<button type="button" class="btn btn-outline-secondary waves-effect waves-themed mb-2" style="border: 1px dashed;" onclick="Addgrouping()"><span class="fal fa-plus mr-1"></span>新增</button>
</div>
<div class="pr-3 row col">
<div class="frame-wrap" id="groupinglist">
</div>
</div>
<div class="card border mb-g w-100 mb-5" id="Tablecard">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-between">
<div class="card-title font-weight-bold">人員清單</div>
<div class="text-right ">
<a href="javascript:;" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" id="addUser-btn" onclick="AddMember()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="emergencyMember_Table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>組別</th>
<th>姓名</th>
<th>部門</th>
<th>電話</th>
<th>Line ID</th>
<th>email</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="emergency-grouping-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered " role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
編組設定
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form id="emergency-grouping-form">
<div class="row">
<div class="form-group col-6">
<label class="form-label" for="emergency_grouping_priority"><span class="text-danger">*</span>排序號</label>
<input class="form-control" type="number" id="emergency_grouping_priority" min="1" />
</div>
<div class="form-group col-6">
<label class="form-label" for="emergency_grouping_name"><span class="text-danger">*</span>組別名稱</label>
<input class="form-control" type="text" id="emergency_grouping_name" />
</div>
</div>
</form>
</div>
<div class="row">
<div class="col-6">
<div class="align-items-center " style="display:flex;flex-wrap: wrap;padding:1rem; " id="deletebtn">
<button type="button" class="btn btn-danger" onclick="DeletedGrouping()">刪除</button>
</div>
</div>
<div class="col-6">
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="SaveGrouping()">儲存</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="emergency-member-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered " role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
人員編組新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form id="emergency-member-form">
<div class="row">
<div class="form-group col-6">
<label class="form-label" for="emergency_member_name"><span class="text-danger">*</span>姓名</label>
<input class="form-control" type="text" id="emergency_member_name" name="emergency_member_name">
</div>
<div class="form-group col-6">
<label class="form-label" for="emergency_member_dept"><span class="text-danger">*</span>部門</label>
<select class="form-control" id="emergency_member_dept">
</select>
</div>
<div class="form-group col-6">
<label class="form-label" for="emergency_member_phone"><span class="text-danger">*</span>電話</label>
<input class="form-control" type="text" id="emergency_member_phone" name="emergency_member_phone"/>
</div>
<div class="form-group col-6">
<label class="form-label" for="emergency_member_lineid"><span class="text-danger">*</span>LINE ID</label>
<input class="form-control" type="text" id="emergency_member_lineid" name="emergency_member_lineid"/>
</div>
<div class="form-group col-6">
<label class="form-label" for="emergency_member_email"><span class="text-danger">*</span>Email</label>
<input class="form-control" type="text" id="emergency_member_email" name="emergency_member_email"/>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="SaveMember()">儲存</button>
</div>
</div>
</div>
</div>
@section Scripts{
<script>
var Selectadisaster;
var selectgroupid = 0;
var selectemergency_member_guid;
var emergencyMemberTable;
$(function () {
emergencyMemberTable = $("#emergencyMember_Table").DataTable({
"columns": [
{
"data": "emergency_member_guid",
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "grouping_name"
},
{
"data": "full_name"
},
{
"data": "department_name"
},
{
"data": "phone"
},
{
"data": "lineid"
},
{
"data": "email"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('guid', data.emergency_member_guid);
},
"ajax": {
"url": "/EmergencyGrouping/Emergency_member_table",
"type": "POST",
"data": function (d) {
d.grouping = selectgroupid
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data.data;
if (data == null || data.length == 0) {
this.data = [];
} else {
}
if (selectgroupid == 0) {
$('#Tablecard').hide();
} else {
$('#Tablecard').show();
}
/*$('#floorcard').hide();*/
return data;
}
}
});
GetDisasterList();
Getdepartlist();
})
//新增人員驗證
var memberValidate = $("#emergency-member-form").validate({
rules: {
emergency_member_name: {
required: true,
},
emergency_member_phone: {
required: true,
},
emergency_member_lineid: {
required: true,
},
emergency_member_email: {
required: true,
email: true
},
}
});
//儲存人員
function SaveMember() {
if ($("#emergency-member-form").valid()) {
var url = "/EmergencyGrouping/SaveMember";
var send_data = {
emergency_member_guid: selectemergency_member_guid,
grouping: selectgroupid,
full_name: $('#emergency_member_name').val(),
department: $('#emergency_member_dept').val(),
phone: $('#emergency_member_phone').val(),
lineid: $('#emergency_member_lineid').val(),
email: $('#emergency_member_email').val()
};
SaveSpinner(1);
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
SaveSpinner(0);
return;
}
else {
toast_ok(rel.msg);
emergencyMemberTable.ajax.reload();
$('#emergency-member-modal').modal('hide');
SaveSpinner(0);
return;
}
}, 'json');
}
}
//取得部門
function Getdepartlist() {
var url = "/EmergencyGrouping/Getdepartlist";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
//$('#Disasterlist').empty();
var Disasterstr = "";
$.each(rel.data, function (index, val) {
$('#emergency_member_dept').append($("<option />").val(val.value).text(val.name));
});
$('#emergency_member_dept').append(Disasterstr);
return;
}
}, 'json');
}
//新增人員
function AddMember() {
console.log($('#groupinglist').find('.btn-success').parent('div').attr('grouping'));
selectgroupid = $('#groupinglist').find('.btn-success').parent('div').attr('grouping');
$("#emergency-member-form").trigger("reset");
selectemergency_member_guid = "";
$('#emergency-member-modal').modal();
}
//取得災難類別
function GetDisasterList() {
var url = "/EmergencySetting/DisasterList";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#Disasterlist').empty();
var Disasterstr = "";
$.each(rel.data, function (index, val) {
if (index == 0) {
Disasterstr += '<button type="button" class="btn btn-success waves-effect waves-themed" onclick = "SelectDisaster(' + val.value + ',this)">' + val.name + '</button>';
}
else {
Disasterstr += '<button type="button" class="btn btn-secondary waves-effect waves-themed" onclick = "SelectDisaster(' + val.value + ',this)">' + val.name + '</button>';
}
});
$('#Disasterlist').append(Disasterstr);
$('#Disasterlist').find('.btn-success').trigger('click');
return;
}
}, 'json');
}
//選擇災難類別
function SelectDisaster(Disaster, e) {
Selectadisaster = Disaster;
if ($("#Disasterlist").find('.btn').hasClass("btn-success")) {
$("#Disasterlist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).removeClass("btn-secondary").addClass("btn-success");
GetGroupingList();
selectgroupid = 0;
emergencyMemberTable.ajax.reload();
}
//新增編組
function Addgrouping() {
/*var last = selectgroupid;*/
selectgroupid = 0;
$("#emergency-grouping-form").trigger("reset");
var a = $('#groupinglist').find('.btn-group').length;
$('#emergency_grouping_priority').val(a + 1);
$('#deletebtn').hide();
$('#emergency-grouping-modal').modal();
}
//儲存編組
function SaveGrouping() {
var url = "/EmergencyGrouping/SaveGrouping";
var send_data = {
id: selectgroupid,
priority: $('#emergency_grouping_priority').val(),
name: $('#emergency_grouping_name').val(),
disaster: Selectadisaster
};
SaveSpinner(1);
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
SaveSpinner(0);
return;
}
else {
toast_ok(rel.msg);
GetGroupingList();
$('#emergency-grouping-modal').modal('hide');
SaveSpinner(0);
return;
}
}, 'json');
}
//取得編組列表
function GetGroupingList() {
var url = "/EmergencyGrouping/GetGroupingList";
var send_data = {
system_parent_id: Selectadisaster
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
var grouping = "";
$('#groupinglist').empty();
$.each(rel.data, function (index, val) {
if (val.id == selectgroupid) {
grouping += '<div class="btn-group mb-2 mr-2" grouping = "' + val.id + '">';
grouping += '<button type="button" class="btn btn-success select" onclick="SelectGrouping(' + val.id + ',this)">' + val.name + '</button>';
grouping += '<button type="button" class="btn btn-success edit" ><i class="fal fa-pencil"></i></button>';
grouping += '</div>';
} else {
grouping += '<div class="btn-group mb-2 mr-2" grouping = "' + val.id + '">';
grouping += '<button type="button" class="btn btn-secondary select" onclick="SelectGrouping(' + val.id + ',this)">' + val.name + '</button>';
grouping += '<button type="button" class="btn btn-secondary edit" ><i class="fal fa-pencil"></i></button>';
grouping += '</div>';
}
});
$('#groupinglist').append(grouping);
return;
}
}, 'json');
}
//編輯編組列表單一資料
$('#groupinglist').on("click", "button.edit", function () {
$('#deletebtn').show();
selectgroupid = $(this).parents('div').attr('grouping');
if ($("#groupinglist").find('.btn').hasClass("btn-success")) {
$("#groupinglist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(this).parent('div').find('.btn').removeClass("btn-secondary").addClass("btn-success");
var url = "/EmergencyGrouping/GetOneGrouping";
var send_data = {
selectgroupid: selectgroupid
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#emergency_grouping_priority').val(rel.data.priority);
$('#emergency_grouping_name').val(rel.data.name);
$('#emergency-grouping-modal').modal();
return;
}
}, 'json');
emergencyMemberTable.ajax.reload();
});
//刪除編組列表
function DeletedGrouping() {
var send_data = {
selectgroupid: selectgroupid
};
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
if ($("#emergencyMember_Table").find(".dataTables_empty").length != 1) {
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: '需先刪除所有相關人員才可進行刪除',
});
return;
} else {
var url = "/EmergencyGrouping/DeleteOne/";
$.post(url, send_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
selectgroupid = 0;
$('#emergency-grouping-modal').modal('hide');
GetGroupingList();
}, 'json');
}
}
});
}
//選擇編組列表
function SelectGrouping(id, e) {
selectgroupid = id;
if ($("#groupinglist").find('.btn').hasClass("btn-success")) {
$("#groupinglist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).parent('div').find('.btn').removeClass("btn-secondary").addClass("btn-success");
emergencyMemberTable.ajax.reload();
}
//編輯人員單一資料
$('#emergencyMember_Table').on("click", "button.edit-btn", function () {
var url = "/EmergencyGrouping/GetOneMember";
selectemergency_member_guid = $(this).parents('tr').attr('guid');
var send_data = {
guid: selectemergency_member_guid
};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
}
else {
$('#emergency_member_name').val(rel.data.full_name);
$('#emergency_member_dept').val(rel.data.department);
$('#emergency_member_phone').val(rel.data.phone);
$('#emergency_member_lineid').val(rel.data.lineid);
$('#emergency_member_email').val(rel.data.email);
$('.modal-title').html("人員編組編輯");
$('#emergency-member-modal').modal();
}
}, 'json');
});
//刪除人員單一資料
$('#emergencyMember_Table').on("click", "button.del-btn", function () {
var url = "/EmergencyGrouping/DeletedOneMember";
selectemergency_member_guid = $(this).parents('tr').attr('guid');
var send_data = {
guid: selectemergency_member_guid
};
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
}
else {
emergencyMemberTable.ajax.reload();
toast_ok(rel.msg);
}
}, 'json');
}
})
})
</script>
}

View File

@ -0,0 +1,416 @@
@{
ViewData["MainNum"] = "4";
ViewData["SubNum"] = "3";
ViewData["Title"] = "紀錄查詢";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">首頁</a></li>
<li class="breadcrumb-item active">紀錄查詢</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<div class="subheader">
<h1 class="subheader-title">
<span>紀錄查詢</span>
</h1>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<div class="btn-group btn-group-md" id="Disasterlist">
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<div class="btn-group btn-group-md" id="buildlist">
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3">
<div class="pr-3 ">
<div class="btn-group btn-group-md" id="Typelist">
<button type="button" class="btn btn-success waves-effect waves-themed mb-2" onclick="SelectType(2,this)">全選</button>
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="SelectType(1,this)">演習</button>
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="SelectType(0,this)">正式</button>
</div>
</div>
<div class="pr-3">
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="ChangeDate30()">近30天</button>
</div>
<div class="pr-3">
<div class="form-group">
<input class="form-control" id="date-range" type="text" name="date" value="">
</div>
</div>
</div>
<div class="card border mb-g w-100 mb-5 " id="menucard">
<div class="mb-2 card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-end">
<div class="text-right ">
<a href="javascript:;" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" id="addUser-btn" onclick="AddFloor()"> 匯出PDF</a>
<a href="javascript:;" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" id="addUser-btn" onclick="AddFloor()"> 匯出Excel</a>
</div>
</div>
<div class="card border mb-g mb-2 m-3" id="menucard">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-between">
<div class="card-title font-weight-bold">事件列表</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="emergency_event_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>棟別</th>
<th>災別</th>
<th>設備</th>
<th>類別</th>
<th>時間</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="card border mb-g mb-2 m-3" id="emergencyitem" style="display:none">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-between">
<div class="card-title font-weight-bold">事件明細</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="emergency_item_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>項目</th>
<th>步驟</th>
<th>是否完成操作</th>
<th>不執行原因</th>
<th>時間</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var SelectaDisaster;
var SelectaBuild;
var SelectaType = 2;//2:全選 1:演習 0:正式
var datepicker;
var EmergencyEventTable;
var EmergencyItemTable;
var SelectEvent;
$(function () {
//#region Date-Picker
datepicker = $('#date-range').daterangepicker({
autoUpdateInput: false,
locale: {
format: 'YYYY/MM/DD',
cancelLabel: '取消',
applyLabel:'確定'
},
opens: 'left'
}, function (start, end, label) {
@* console.log("A new date selection was made: " + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD'));*@
});
$('#date-range').on('apply.daterangepicker', function (ev, picker) {
$(this).val(picker.startDate.format('YYYY/MM/DD') + ' - ' + picker.endDate.format('YYYY/MM/DD'));
$(this).trigger('change');
});
$('#date-range').on('cancel.daterangepicker', function (ev, picker) {
$(this).val('');
$(this).trigger('change');
});
//#endregion
var today = new Date();
var dateLimit = new Date(new Date().setDate(today.getDate() - 30));
var today_format = today.toISOString().slice(0, 10).replace(/-/g, "/");
var dateLimit_format = dateLimit.toISOString().slice(0, 10).replace(/-/g, "/");
datepicker.data('daterangepicker').setStartDate(dateLimit_format);
datepicker.data('daterangepicker').setEndDate(today_format);
$('#date-range').val(dateLimit_format + ' - ' + today_format);
EmergencyEventTable = $("#emergency_event_table").DataTable({
"order": [[5, "desc"]],
"columns": [
{
"data": "emergency_event_guid",
"render": function (data, type, row, meta) {
return meta.row + 1;
},
},
{
"data": "building_name"
},
{
"data": "disaster_name"
},
{
"data": "device_name"
},
{
"data": "type"
},
{
"data": "created_at"
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('guid', data.emergency_event_guid);
$(row).attr('type', data.type);
$(row).attr('device', data.device_name);
},
"ajax": {
"url": "/EmergencyRecord/EmergencyRecordTable",
"type": "POST",
"data": function (d) {
d.selectaDisaster = SelectaDisaster,
d.selectaBuild = SelectaBuild,
d.selectaType = SelectaType,
d.dateranger = $('#date-range').val()
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data.data;
if (data == null || data.length == 0) {
this.data = [];
}
$.each(this.data,function(index, val) {
if (val.type == 0) {
val.type = "正式";
} else {
val.type = "演習";
}
})
return data;
}
}
});
EmergencyItemTable = $('#emergency_item_table').DataTable({
"order": [[4, "desc"]],
"columns": [
{
"data": "big_setting"
},
{
"data": "step_setting"
},
{
"data": "finished"
},
{
"data": "reason"
},
{
"data": "updated_at"
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('guid', data.emergency_item_guid);
},
"ajax": {
"url": "/EmergencyRecord/EmergencyItemTable",
"type": "POST",
"data": function (d) {
d.event_guid = SelectEvent
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data.data;
if (data == null || data.length == 0) {
this.data = [];
}
$.each(this.data, function (index, val) {
if (val.finished == 0) {
val.finished = "未執行";
}
else if (val.finished == 1)
{
val.type = "完成";
}
else
{
val.type = "不執行";
}
})
return data;
}
}
});
GetDisasterList();
GetBuild();
})
//取得所有災難別
function GetDisasterList() {
var url = "/EmergencySetting/DisasterList";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#Disasterlist').empty();
var Disasterstr = "";
$.each(rel.data, function (index, val) {
if (index == 0) {
Disasterstr += '<button type="button" class="btn btn-success waves-effect waves-themed" onclick = "SelectDisaster(' + val.value + ',this)"> ' + val.name + '</button>';
}
else {
Disasterstr += '<button type="button" class="btn btn-secondary waves-effect waves-themed" onclick = "SelectDisaster(' + val.value + ',this)">' + val.name + '</button>';
}
});
$('#Disasterlist').append(Disasterstr);
$('#Disasterlist').find('.btn-success').trigger('click');
return;
}
}, 'json');
}
//取得所有棟別
function GetBuild() {
var url = "/BuildMenu/BuildInfoList";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#buildlist').empty();
var buildstr = "";
$.each(rel.data, function (index, val) {
$('#build_menu_building_modal').append($("<option />").val(val.value).text(val.name));
if (index == 0) {
SelectBuild = val.value;
buildstr += '<button type="button" class="btn btn-success waves-effect waves-themed" onclick="SelectBulid(\'' + val.value + '\' ,this)">' + val.name + '</button>';
}
else {
buildstr += '<button type="button" class="btn btn-secondary waves-effect waves-themed" onclick="SelectBulid(\'' + val.value + '\',this)" >' + val.name + '</button>';
}
});
$('#buildlist').append(buildstr);
$('#buildlist').find('.btn-success').trigger('click');
//GetMainlistByBuild(SelectBuild);
return;
}
}, 'json');
}
//選擇災難類別
function SelectDisaster(Disaster, e) {
SelectaDisaster = Disaster;
if ($("#Disasterlist").find('.btn').hasClass("btn-success")) {
$("#Disasterlist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).removeClass("btn-secondary").addClass("btn-success");
reloadeventTable();
}
//選擇棟別
function SelectBulid(build, e) {
SelectaBuild = build;
if ($("#buildlist").find('.btn').hasClass("btn-success")) {
$("#buildlist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).removeClass("btn-secondary").addClass("btn-success");
reloadeventTable();
}
//選擇類別(正式 or 演習)
function SelectType(type, e) {
SelectaType = type
if ($("#Typelist").find('.btn').hasClass("btn-success")) {
$("#Typelist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).removeClass("btn-secondary").addClass("btn-success");
reloadeventTable();
}
//查詢近30天
function ChangeDate30() {
var today = new Date();
var dateLimit = new Date(new Date().setDate(today.getDate() - 30));
var today_format = today.toISOString().slice(0, 10).replace(/-/g, "/");
var dateLimit_format = dateLimit.toISOString().slice(0, 10).replace(/-/g, "/");
datepicker.data('daterangepicker').setStartDate(dateLimit_format);
datepicker.data('daterangepicker').setEndDate(today_format);
$('#date-range').val(dateLimit_format + ' - ' + today_format);
$('#date-range').trigger('change');
}
//改變日期
$('#date-range').on('change', function () {
reloadeventTable();
});
//點選Event
$('#emergency_event_table').on("click", "tbody>tr", function () {
$(this).parents().find('tr').css('background-color', '#fff');
$(this).css('background-color', '#67B4AC');
SelectEvent = $(this).attr('guid');
$('#emergencyitem').find('.card-title').html("事件明細" + "-" + $(this).attr('type') + "-" + $(this).attr('device'));
EmergencyItemTable.ajax.reload();
$('#emergencyitem').show();
})
//重新執行EventTable
function reloadeventTable() {
EmergencyEventTable.ajax.reload();
$('#emergencyitem').hide();
}
</script>
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
</div>

View File

@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>

View File

@ -0,0 +1,81 @@
@{
Layout = null;
}
@model Backend.Models.ForgotPasswordViewModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>忘記密碼 | IBMS後台管理系統</title>
<!-- base css -->
<link id="vendorsbundle" rel="stylesheet" media="screen, print" href="~/css/vendors.bundle.css">
<link id="appbundle" rel="stylesheet" media="screen, print" href="~/css/app.bundle.css">
<link id="mytheme" rel="stylesheet" media="screen, print" href="~/css/themes/cust-theme-8.css">
<link id="myskin" rel="stylesheet" media="screen, print" href="~/css/skins/skin-master.css">
<!-- Place favicon.ico in the root directory -->
<link rel="apple-touch-icon" sizes="180x180" href="~/img/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="~/img/favicon/favicon-32x32.png">
<link rel="mask-icon" href="~/img/favicon/safari-pinned-tab.svg" color="#5bbad5">
<link rel="stylesheet" media="screen, print" href="~/css/page-login-alt.css">
<!-- Font Awesome -->
<link href="~/lib/fontawesome-free/css/all.min.css" rel="stylesheet" />
<!-- icheck bootstrap -->
<link href="~/lib/icheck-bootstrap/icheck-bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="blankpage-form-field">
<div class="page-logo m-0 w-100 align-items-center justify-content-center rounded border-bottom-left-radius-0 border-bottom-right-radius-0 px-2">
<div class="w-100 page-logo-link press-scale-down d-flex align-items-center">
<img src="/img/dome.png" width="50%" aria-roledescription="logo">
<span class="page-logo-text">IBMS後台管理系統</span>
</div>
</div>
<div class="card p-4 border-top-left-radius-0 border-top-right-radius-0">
@if (ViewBag.ErrMsg != null && ViewBag.ErrMsg != "")
{
<p class="alert alert-danger">@ViewBag.ErrMsg</p>
}
<form asp-action="ForgotPassword" method="post">
<div class="mb-3">
<div class="input-group">
<input asp-for="Email" type="email" class="form-control" placeholder="Email">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope"></span>
</div>
</div>
</div>
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="row">
<div class="col-12">
<button type="submit" class="btn btn-default float-right">取得新密碼</button>
</div>
<!-- /.col -->
</div>
</form>
</div>
<div class="blankpage-footer text-center">
<a asp-controller="Login" asp-action="Index"><strong>返回登入</strong></a>
</div>
</div>
<video poster="~/img/backgrounds/clouds.png" id="bgvid" playsinline autoplay muted loop>
<source src="~/media/video/cc.webm" type="video/webm">
<source src="~/media/video/cc.mp4" type="video/mp4">
</video>
<!-- jQuery -->
<script src="~/lib/jquery/dist/jquery.js"></script>
<!-- Bootstrap 4 -->
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
@*<script src="~/js/adminlte.min.js"></script>*@
<script src="~/js/vendors.bundle.js"></script>
<script src="~/js/app.bundle.js"></script>
</body>
</html>

View File

@ -0,0 +1,132 @@
@{
Layout = null;
}
@model Backend.Models.LoginViewModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>登入 | IBMS後台管理系統</title>
<!-- base css -->
<link id="vendorsbundle" rel="stylesheet" media="screen, print" href="~/css/vendors.bundle.css">
<link id="appbundle" rel="stylesheet" media="screen, print" href="~/css/app.bundle.css">
<link id="mytheme" rel="stylesheet" media="screen, print" href="~/css/themes/cust-theme-8.css">
<link id="myskin" rel="stylesheet" media="screen, print" href="~/css/skins/skin-master.css">
<!-- Place favicon.ico in the root directory -->
<link rel="apple-touch-icon" sizes="180x180" href="~/img/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="~/img/favicon/favicon-32x32.png">
<link rel="mask-icon" href="~/img/favicon/safari-pinned-tab.svg" color="#5bbad5">
<link rel="stylesheet" media="screen, print" href="~/css/page-login-alt.css">
<!-- Font Awesome -->
<link href="~/lib/fontawesome-free/css/all.min.css" rel="stylesheet" />
<!-- icheck bootstrap -->
<link href="~/lib/icheck-bootstrap/icheck-bootstrap.min.css" rel="stylesheet" />
<!-- Theme style -->
</head>
<body>
<div class="blankpage-form-field">
<div class="page-logo m-0 w-100 align-items-center justify-content-center rounded border-bottom-left-radius-0 border-bottom-right-radius-0 px-2">
<div class="w-100 page-logo-link press-scale-down d-flex align-items-center">
<img src="/img/dome.png" width="50%" aria-roledescription="logo">
<span class="page-logo-text">IBMS後台管理系統</span>
</div>
</div>
<div class="card p-4 border-top-left-radius-0 border-top-right-radius-0">
@if (ViewBag.ErrMsg != null && ViewBag.ErrMsg != "")
{
<p class="alert alert-danger">@ViewBag.ErrMsg</p>
}
<form id="login-form" asp-action="Index" method="post">
<div class="form-group">
<label class="form-label" for="username">帳號</label>
<input asp-for="Account" type="text" id="account" class="form-control" placeholder="Account">
<span asp-validation-for="Account" class="text-danger"></span>
<span class="help-block">
您的帳號
</span>
</div>
<div class="form-group">
<label class="form-label" for="password">密碼</label>
<input asp-for="Password" type="password" id="password" class="form-control" placeholder="Password" autocomplete="off">
<span asp-validation-for="Password" class="text-danger"></span>
<span class="help-block">
您的密碼
</span>
</div>
<div class="form-group text-left">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="rememberme">
<label class="custom-control-label" for="rememberme"> 記住我</label>
</div>
</div>
<button type="submit" class="btn btn-default float-right">登入</button>
</form>
</div>
<div class="blankpage-footer text-center">
<a asp-controller="Login" asp-action="ForgotPassword"><strong>忘記密碼</strong></a>
</div>
</div>
<video poster="~/img/backgrounds/clouds.png" id="bgvid" playsinline autoplay muted loop>
<source src="~/media/video/cc.webm" type="video/webm">
<source src="~/media/video/cc.mp4" type="video/mp4">
</video>
<!-- jQuery -->
<script src="~/lib/jquery/dist/jquery.js"></script>
<!-- Bootstrap 4 -->
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/vendors.bundle.js"></script>
<script src="~/js/app.bundle.js"></script>
</body>
</html>
<script>
var remember = false;
$(function () {
if (localStorage.getItem('solar-t') == 'true') {
document.getElementById("rememberme").checked = true;
remember = true;
$("#account").val(atob(localStorage.getItem('solar-a')));
$("#password").val(atob(localStorage.getItem('solar-p')));
}
else {
document.getElementById("rememberme").checked = false;
}
});
$("#rememberme").click(function () {
if (remember) {
localStorage.setItem('solar-t', 'false');
localStorage.removeItem('solar-a');
localStorage.removeItem('solar-p');
remember = false;
} else {
localStorage.setItem('solar-t', 'true');
localStorage.setItem('solar-a', btoa($("#account").val()));
localStorage.setItem('solar-p', btoa($("#password").val()));
remember = true;
}
});
$("#account").change(function () {
if (remember) {
localStorage.setItem('solar-a', btoa($("#account").val()));
} else {
localStorage.removeItem('solar-a');
}
});
$("#password").change(function () {
if (remember) {
localStorage.setItem('solar-p', btoa($("#password").val()));
} else {
localStorage.removeItem('solar-p');
}
});
</script>

View File

@ -0,0 +1,398 @@
@{
ViewData["MainNum"] = "3";
ViewData["SubNum"] = "4";
ViewData["Title"] = "AED裝置設定";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">首頁</a></li>
<li class="breadcrumb-item active">AED裝置設定</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<div class="subheader">
<h1 class="subheader-title">
<span>AED裝置設定</span>
</h1>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<div class="btn-group btn-group-md" id="Buildinglist">
@*<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2 mr-2">123</button>*@
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AllFloor()">全選</button>
</div>
<div class="pr-3 row col">
<div class="frame-wrap" id="floorlist">
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3">
<div class="card border mb-g w-100 mb-5" id="menucard">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-between">
<div class="card-title font-weight-bold">AED裝置設定</div>
<div class="text-right ">
<button type="button" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" id="import-file-btn" onclick="$('#import_file_input').click()"><span class="fal fa-plus mr-1"></span>匯入Excel</button>
<input id="import_file_input" type="file" name="import_file_input" onchange="importRawDataFile()" style="display:none" multiple accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />
<button type="button" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" onclick="ExportExcel()"><span class="fal fa-file-excel mr-1"></span> 匯出Excel</button>
</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="RescueDeviceTable" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>樓層</th>
<th>設備編號</th>
<th>位置</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="FireExtinguisher-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered " role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form id="FireExtinguisher-form">
<div class="row">
<div class="form-group col-12">
<label class="form-label" for="FireExtinguisher_location_modal"><span class="text-danger">*</span>位置</label>
<input class="form-control" id="FireExtinguisher_location_modal" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="SaveFireExtinguisher()">儲存</button>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var SelectBuild;
var SelectFloorList = new Array(0);
var AllFloorList = new Array(0);
var FireExtinguisherTable;
var selectAllFloor = false;
var SelectDevice;
$(function () {
FireExtinguisherTable = $("#RescueDeviceTable").DataTable({
"columns": [
{
"data": "floor_name"
},
{
"data": "rescue_device_id"
},
{
"data": "location"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('guid', data.rescue_device_guid);
},
"ajax": {
"url": "/RescueDevice/RescueDeviceTable",
"type": "POST",
"data": function (d) {
d.build = SelectBuild,
d.floors = SelectFloorList,
d.kind = 1
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
GetBuild();
});
function GetBuild() {
var url = "/BuildMenu/BuildInfoList";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#Buildinglist').empty();
var buildstr = "";
$.each(rel.data, function (index, val) {
if (index == 0) {
SelectBuild = val.value;
buildstr += '<button type="button" class="btn btn-success waves-effect waves-themed" onclick="SelectBulid(\'' + val.value + '\' ,this)">' + val.name + '</button>';
}
else {
buildstr += '<button type="button" class="btn btn-secondary waves-effect waves-themed" onclick="SelectBulid(\'' + val.value + '\',this)" >' + val.name + '</button>';
}
});
$('#Buildinglist').append(buildstr);
$('#Buildinglist').find('.btn-success').trigger('click');
return;
}
}, 'json');
}
function SelectBulid(build, e) {
SelectBuild = build;
if ($("#Buildinglist").find('.btn').hasClass("btn-success")) {
$("#Buildinglist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).removeClass("btn-secondary").addClass("btn-success");
//$('#menucard').find('.card-title').html(e.innerText + "-選單");
GetFloorByBuild(SelectBuild);
}
function GetFloorByBuild(build) {
var url = "/RescueDevice/GetFloorByBuild";
var send_data = { Building: build };
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#floorlist').empty();
SelectFloorList = [];
AllFloorList = [];
var floorstr = "";
$.each(rel.data, function (index, val) {
AllFloorList.push(val.value);
floorstr += '<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2 mr-2" onclick="SelectFloor(\'' + val.value + '\',this)" >' + val.name + '</button>';
});
$('#floorlist').append(floorstr);
AllFloor();
//$('#floorlist').find('.btn-success').trigger('click');
return;
}
}, 'json');
}
function SelectFloor(floorguid, e) {
if ($(e).hasClass("btn-outline-success")) {
$(e).removeClass("btn-outline-success").addClass("btn-success");
SelectFloorList.push(floorguid);
} else if ($(e).hasClass("btn-success")) {
$(e).removeClass("btn-success").addClass("btn-outline-success");
var a = SelectFloorList.filter(function (n, i) {
if (n === floorguid) {
SelectFloorList.splice(i, 1);
}
});
}
FireExtinguisherTable.ajax.reload();
}
function AllFloor() {
if (selectAllFloor) {
SelectFloorList = [];
$('#floorlist').find('.btn').removeClass('btn-success').addClass("btn-outline-success");
selectAllFloor = false;
} else {
SelectFloorList = AllFloorList;
$('#floorlist').find('.btn').removeClass('btn-outline-success').addClass("btn-success");
selectAllFloor = true;
}
FireExtinguisherTable.ajax.reload();
}
function importRawDataFile() {
import_files = $('#import_file_input')[0].files[0];
Swal.fire(
{
title: "設備檔案匯入",
text: "匯入檔案會將舊有資料完全移除,你確定是否要匯入?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/RescueDevice/ImportRescueDevice";
var formData = new FormData();
formData.append("import_file", import_files);
formData.append("kind", 1);
formData.append("building", SelectBuild);
$("#import-file-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
$.ajax({
type: "POST",
url: url,
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (rel) {
$("#import_file_input").val('');
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
FireExtinguisherTable.ajax.reload(null, false);
}
$("#import-file-btn").html('<span class="fal fa-plus mr-1"></span>匯入Excel').attr("disabled", false);
return;
}
else {
toast_ok(rel.msg);
$("#import-file-btn").html('<span class="fal fa-plus mr-1"></span>匯入Excel').attr("disabled", false);
FireExtinguisherTable.ajax.reload(null, false);
return;
}
},
});
}
});
}
$('#RescueDeviceTable').on("click", "button.del-btn", function () {
var send_data = {
guid: $(this).parents('tr').attr('guid'),
};
Swal.fire(
{
title: "刪除設備",
text: "是否刪除該AED?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/RescueDevice/DeletedIt";
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
else {
toast_ok(rel.msg);
FireExtinguisherTable.ajax.reload(null, false);
return;
}
});
}
})
})
$('#RescueDeviceTable').on("click", "button.edit-btn", function () {
SelectDevice = $(this).parents('tr').attr('guid');
var send_data = {
guid: SelectDevice,
};
var url = "/RescueDevice/GetLocation";
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
else {
$('#FireExtinguisher-modal').find('.modal-title').html(rel.data.rescue_device_id + "-" + rel.data.floor_name);
$('#FireExtinguisher_location_modal').val(rel.data.location);
//toast_ok(rel.msg);
FireExtinguisherTable.ajax.reload(null, false);
return;
}
});
$('#FireExtinguisher-modal').modal();
})
function SaveFireExtinguisher() {
var send_data = {
guid: SelectDevice,
location: $('#FireExtinguisher_location_modal').val()
};
var url = "/RescueDevice/SaveFireExtinguisher";
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
else {
$('#FireExtinguisher-modal').modal('hide');
toast_ok(rel.msg);
FireExtinguisherTable.ajax.reload();
return;
}
});
}
function ExportExcel() {
var send_data = {
build: SelectBuild,
buildname: $('#Buildinglist').find('.btn-success').html(),
kind: 1
};
var url = "/RescueDevice/ExportExcel";
window.location = "/RescueDevice/ExportExcel?post=" + JSON.stringify(send_data);
return;
}
</script>
}

View File

@ -0,0 +1,417 @@
@{
ViewData["MainNum"] = "3";
ViewData["SubNum"] = "3";
ViewData["Title"] = "滅火器設定";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">首頁</a></li>
<li class="breadcrumb-item active">滅火器設定</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<div class="subheader">
<h1 class="subheader-title">
<span>滅火器設定</span>
</h1>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<div class="btn-group btn-group-md" id="Buildinglist">
@*<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2 mr-2">123</button>*@
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3 justify-content-between">
<div class="pr-3 ">
<button type="button" class="btn btn-secondary waves-effect waves-themed mb-2" onclick="AllFloor()">全選</button>
</div>
<div class="pr-3 row col">
<div class="frame-wrap" id="floorlist">
</div>
</div>
</div>
<div class="row mb-3 d-flex align-items-center px-3">
<div class="card border mb-g w-100 mb-5" id="menucard">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-between">
<div class="card-title font-weight-bold">滅火器列表</div>
<div class="text-right ">
<button type="button" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" id="import-file-btn" onclick="$('#import_file_input').click()"><span class="fal fa-plus mr-1"></span>匯入Excel</button>
<input id="import_file_input" type="file" name="import_file_input" onchange="importRawDataFile()" style="display:none" multiple accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />
<button type="button" class="btn btn-sm btn-success ml-auto waves-effect waves-themed" onclick="ExportExcel()"><span class="fal fa-file-excel mr-1"></span> 匯出Excel</button>
</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="RescueDeviceTable" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>樓層</th>
<th>設備編號</th>
<th>位置</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="FireExtinguisher-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered " role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form id="FireExtinguisher-form">
<div class="row">
<div class="form-group col-12">
<label class="form-label" for="FireExtinguisher_location_modal"><span class="text-danger">*</span>位置</label>
<input class="form-control" id="FireExtinguisher_location_modal"/>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="SaveFireExtinguisher()">儲存</button>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var SelectBuild;
var SelectFloorList = new Array(0);
var AllFloorList = new Array(0);
var FireExtinguisherTable;
var selectAllFloor = false;
var SelectDevice;
$(function () {
FireExtinguisherTable = $("#RescueDeviceTable").DataTable({
"columns": [
{
"data": "floor_name"
},
{
"data": "rescue_device_id"
},
{
"data": "location"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('guid', data.rescue_device_guid);
},
"ajax": {
"url": "/RescueDevice/RescueDeviceTable",
"type": "POST",
"data": function (d) {
d.build = SelectBuild,
d.floors = SelectFloorList,
d.kind = 0
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
GetBuild();
});
function GetBuild() {
var url = "/BuildMenu/BuildInfoList";
var send_data = {};
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#Buildinglist').empty();
var buildstr = "";
$.each(rel.data, function (index, val) {
if (index == 0) {
SelectBuild = val.value;
buildstr += '<button type="button" class="btn btn-success waves-effect waves-themed" onclick="SelectBulid(\'' + val.value + '\' ,this)">' + val.name + '</button>';
}
else {
buildstr += '<button type="button" class="btn btn-secondary waves-effect waves-themed" onclick="SelectBulid(\'' + val.value + '\',this)" >' + val.name + '</button>';
}
});
$('#Buildinglist').append(buildstr);
$('#Buildinglist').find('.btn-success').trigger('click');
return;
}
}, 'json');
}
function SelectBulid(build, e) {
SelectBuild = build;
if ($("#Buildinglist").find('.btn').hasClass("btn-success")) {
$("#Buildinglist").find('.btn').removeClass("btn-success").addClass("btn-secondary");
}
$(e).removeClass("btn-secondary").addClass("btn-success");
//$('#menucard').find('.card-title').html(e.innerText + "-選單");
GetFloorByBuild(SelectBuild);
}
function GetFloorByBuild(build) {
var url = "/RescueDevice/GetFloorByBuild";
var send_data = { Building: build };
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
return;
}
else {
$('#floorlist').empty();
SelectFloorList = [];
AllFloorList = [];
var floorstr = "";
$.each(rel.data, function (index, val) {
AllFloorList.push(val.value);
floorstr += '<button type="button" class="btn btn-outline-success waves-effect waves-themed mb-2 mr-2" onclick="SelectFloor(\'' + val.value + '\',this)" >' + val.name + '</button>';
});
$('#floorlist').append(floorstr);
AllFloor();
//$('#floorlist').find('.btn-success').trigger('click');
return;
}
}, 'json');
}
function SelectFloor(floorguid, e) {
if ($(e).hasClass("btn-outline-success")) {
$(e).removeClass("btn-outline-success").addClass("btn-success");
SelectFloorList.push(floorguid);
} else if ($(e).hasClass("btn-success")) {
$(e).removeClass("btn-success").addClass("btn-outline-success");
var a = SelectFloorList.filter(function (n, i) {
if (n === floorguid) {
SelectFloorList.splice(i, 1);
}
});
}
FireExtinguisherTable.ajax.reload();
}
function AllFloor() {
if (selectAllFloor) {
SelectFloorList = [];
$('#floorlist').find('.btn').removeClass('btn-success').addClass("btn-outline-success");
selectAllFloor = false;
} else {
SelectFloorList = AllFloorList;
$('#floorlist').find('.btn').removeClass('btn-outline-success').addClass("btn-success");
selectAllFloor = true;
}
FireExtinguisherTable.ajax.reload();
}
function importRawDataFile() {
import_files = $('#import_file_input')[0].files[0];
Swal.fire(
{
title: "設備檔案匯入",
text: "匯入檔案會將舊有資料完全移除,你確定是否要匯入?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/RescueDevice/ImportRescueDevice";
var formData = new FormData();
formData.append("import_file", import_files);
formData.append("kind", 0);
formData.append("building", SelectBuild);
$("#import-file-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
$.ajax({
type: "POST",
url: url,
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (rel) {
$("#import_file_input").val('');
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
FireExtinguisherTable.ajax.reload(null, false);
}
$("#import-file-btn").html('<span class="fal fa-plus mr-1"></span>匯入Excel').attr("disabled", false);
return;
}
else {
toast_ok(rel.msg);
$("#import-file-btn").html('<span class="fal fa-plus mr-1"></span>匯入Excel').attr("disabled", false);
FireExtinguisherTable.ajax.reload(null, false);
return;
}
},
});
}
});
}
$('#RescueDeviceTable').on("click", "button.del-btn", function () {
var send_data = {
guid: $(this).parents('tr').attr('guid'),
};
Swal.fire(
{
title: "刪除設備",
text: "是否刪除該滅火器?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/RescueDevice/DeletedIt";
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
else {
toast_ok(rel.msg);
FireExtinguisherTable.ajax.reload(null, false);
return;
}
});
}
})
})
$('#RescueDeviceTable').on("click", "button.edit-btn", function () {
SelectDevice = $(this).parents('tr').attr('guid');
var send_data = {
guid: SelectDevice,
};
var url = "/RescueDevice/GetLocation";
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
else {
$('#FireExtinguisher-modal').find('.modal-title').html(rel.data.rescue_device_id + "-" + rel.data.floor_name);
$('#FireExtinguisher_location_modal').val(rel.data.location);
//toast_ok(rel.msg);
FireExtinguisherTable.ajax.reload(null, false);
return;
}
});
$('#FireExtinguisher-modal').modal();
})
function SaveFireExtinguisher() {
var send_data = {
guid: SelectDevice,
location: $('#FireExtinguisher_location_modal').val()
};
var url = "/RescueDevice/SaveFireExtinguisher";
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
else {
$('#FireExtinguisher-modal').modal('hide');
toast_ok(rel.msg);
FireExtinguisherTable.ajax.reload();
return;
}
});
}
function ExportExcel() {
var send_data = {
build: SelectBuild,
buildname: $('#Buildinglist').find('.btn-success').html(),
kind: 0
};
var url = "/RescueDevice/ExportExcel";
window.location = "/RescueDevice/ExportExcel?post=" + JSON.stringify(send_data);
return;
//$.post(url, send_data, function (rel) {
// if (rel.code == "0000") {
// return;
// }
// else {
// var text = "原因如下:<br\>";
// $.each(rel.data, function (index, val) {
// text += index + 1 + "." + val + "<br\>";
// });
// Swal.fire(
// {
// title: "Excel匯出失敗",
// icon: 'warning',
// html: text,
// });
// }
//}, 'json');
}
</script>
}

View File

@ -0,0 +1,339 @@
@{
ViewData["MainNum"] = "7";
ViewData["SubNum"] = "1";
ViewData["Title"] = "服務計畫";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">服務管理</a></li>
<li class="breadcrumb-item active">服務計畫</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-xl-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<div class="subheader">
<h1 class="subheader-title">
<span>服務計畫</span>
</h1>
</div>
<div class="row mb-3">
<div class="col-12 d-flex justify-content-end">
<a href="javascript:;" class="btn btn-success waves-effect waves-themed mb-3" onclick="AddServicePlan()"><span class="fal fa-plus mr-1"></span>新增計畫</a>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="ServicePlan_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>編號</th>
<th>計畫名稱</th>
<th>狀態</th>
<th>棟別</th>
<th>目標資料表</th>
<th>週期</th>
<th>計畫期間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="ServicePlan-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
服務計畫 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form class="ServicePlan-form" id="ServicePlan-form">
<div class="row">
<div class="form-group col-6">
<label class="form-label" for="ServicePlan-Name"><span class="text-danger">*</span>計畫名稱</label>
<input type="text" id="ServicePlan-Name" class="form-control" name="ServicePlanName">
</div>
<div class="form-group col-6">
<label class="form-label" for="ServicePlan-Building"><span class="text-danger">*</span>棟別</label>
<select class="form-control" id="ServicePlan-Building"></select>
</div>
<div class="form-group col-6">
<label class="form-label" for="ServicePlan-Table"><span class="text-danger">*</span>目標資料表</label>
<input type="text" id="ServicePlan-Table" class="form-control" name="ServicePlanTable">
</div>
<div class="form-group col-6">
<label class="form-label"><span class="text-danger">*</span>週期</label>
<div class="row d-flex justify-content-start align-items-center">
<div class="col-2">每</div>
<div class="col">
<input type="number" id="ServicePlan-execution_time" class="form-control" name="ServicePlanexecution_time">
</div>
<div class="col">
<select class="form-control" id="ServicePlan-execution_type" width="90" style="width: 90px">
<option value="0">分</option>
<option value="1">小時</option>
<option value="2">天</option>
<option value="3">週</option>
<option value="4">月</option>
</select>
</div>
</div>
</div>
<div class="form-group col-6">
<label class="form-label" for="ServicePlan-start_time"><span class="text-danger">*</span>開始時間</label>
<input type="datetime-local" id="ServicePlan-start_time" class="form-control" name="ServicePlanstart_time">
</div>
<div class="form-group col-6">
<label class="form-label" for="ServicePlan-end_time">結束時間</label>
<input type="datetime-local" id="ServicePlan-end_time" class="form-control" name="ServicePlanend_time">
</div>
<div class="form-group col-6">
<label class="form-label" for="ServicePlan-status">狀態</label>
<select class="form-control" id="ServicePlan-status">
<option value="0">啟用</option>
<option value="1">停用</option>
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="SavePlan()">確定</button>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var SelectPlanid = 0;
var ServicePlanTable;
$(function () {
ServicePlanTable = $("#ServicePlan_table").DataTable({
"columns": [
{
"data": "plan_name",
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "plan_name"
},
{
"data": "status"
},
{
"data": "building"
},
{
"data": "target_table"
},
{
"data": "execution"
},
{
"data": "time"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('bg-id', data.id);
},
"ajax": {
"url": "/ServicePlan/GetPlanTable",
"type": "POST",
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
} else {
$.each(this.data, function (k, rel) {
if (rel.status == 0) {
rel.status = '啟用';
} else {
rel.status = '停用';
}
})
}
//$('#floorcard').hide();
return data;
}
}
});
SetBuild();
});
var formValid = $("#ServicePlan-form").validate({
rules: {
ServicePlanName: {
required: true,
maxlength: 50
},
ServicePlanTable: {
required: true,
maxlength: 50
},
ServicePlanexecution_time: {
required: true,
min: 1
},
ServicePlanstart_time: {
required: true
}
}
});
function AddServicePlan() {
SelectPlanid = 0;
formValid.resetForm();
$("#ServicePlan-form").trigger("reset");
$("#ServicePlan-modal .modal-title").html("服務計畫 - 新增");
$("#ServicePlan-modal").modal();
}
function SavePlan() {
var sent_data = {
id: SelectPlanid,
status: $('#ServicePlan-status').val(),
plan_name: $('#ServicePlan-Name').val(),
building_guid: $('#ServicePlan-Building').val(),
target_table: $('#ServicePlan-Table').val(),
execution_time: $('#ServicePlan-execution_time').val(),
execution_type: $('#ServicePlan-execution_type').val(),
start_time: $('#ServicePlan-start_time').val(),
end_time: $('#ServicePlan-end_time').val()
};
//if ($('#ServicePlan-end_time').val() != '0001-01-01 00:00:00') {
// sent_data.append()
//}
var url = "/ServicePlan/SavePlan";
if ($("#ServicePlan-form").valid())
{
$.post(url, sent_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
} else {
toast_ok(rel.msg);
ServicePlanTable.ajax.reload();
$('#ServicePlan-modal').modal('hide');
}
})
}
}
function SetBuild() {
var url = "/BuildInfo/BuildInfoList";
$.post(url, null, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
if (rel.data.length > 0) {
$('#ServicePlan-Building').empty();
$.each(rel.data, function (index, val) {
$("#ServicePlan-Building").append($("<option />").val(val.building_guid).text(val.full_name));
});
} else {
$("#ServicePlan-Building").empty();
$("#ServicePlan-Building").append('<option value="0" disabled>請先新增區域</option>');
$("#ServicePlan-Building").val($("#select_building option:first").val());
}
}, 'json');
}
$('#ServicePlan_table').on("click", "button.edit-btn", function () {
formValid.resetForm();
SelectPlanid = $(this).parents('tr').attr('bg-id');
var url = "/ServicePlan/GetonePlan";
var sent_data =
{
id: SelectPlanid
};
$.post(url, sent_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
$('#ServicePlan-status').val(rel.data.status);
$('#ServicePlan-Name').val(rel.data.plan_name);
$('#ServicePlan-Building').val(rel.data.building_guid);
$('#ServicePlan-Table').val(rel.data.target_table);
$('#ServicePlan-execution_time').val(rel.data.execution_time);
$('#ServicePlan-execution_type').val(rel.data.execution_type);
$('#ServicePlan-start_time').val(rel.data.start_time.replace(" ", "T"));
if (rel.data.end_time == "0001-01-01 00:00:00") {
$('#ServicePlan-end_time').val(null);
} else {
$('#ServicePlan-end_time').val(rel.data.end_time.replace(" ", "T"));
}
$("#ServicePlan-modal").modal();
})
})
$('#ServicePlan_table').on("click", "button.del-btn", function () {
SelectPlanid = $(this).parents('tr').attr('bg-id');
var sent_data =
{
id: SelectPlanid
};
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/ServicePlan/DeletePlan/";
$.post(url, sent_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
ServicePlanTable.ajax.reload(null, false);
}, 'json');
}
});
});
</script>
}

View File

@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@ -0,0 +1,992 @@
<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
<meta charset="utf-8" />
<meta name="description" content="Page Title">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - IBMS後台管理系統</title>
<!-- base css -->
<link id="vendorsbundle" rel="stylesheet" media="screen, print" href="~/css/vendors.bundle.css" asp-append-version="true">
<link id="appbundle" rel="stylesheet" media="screen, print" href="~/css/app.bundle.css" asp-append-version="true">
<link id="mytheme" rel="stylesheet" media="screen, print" href="~/css/themes/cust-theme-8.css" asp-append-version="true">
<link id="myskin" rel="stylesheet" media="screen, print" href="~/css/skins/skin-master.css" asp-append-version="true">
<!-- dataTables -->
<link rel="stylesheet" media="screen, print" href="~/css/datagrid/datatables/datatables.bundle.css">
<!-- SweetAlert -->
<link rel="stylesheet" media="screen, print" href="~/css/notifications/sweetalert2/sweetalert2.bundle.css">
<link rel="stylesheet" media="screen, print" href="~/css/notifications/toastr/toastr.css">
<!--Select2-->
<link rel="stylesheet" media="screen, print" href="~/css/formplugins/select2/select2.bundle.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" type="text/css" media="all" href="~/js/daterangepicker/daterangepicker.css">
</head>
<body class="mod-bg-1 mod-nav-link">
<!-- BEGIN Page Wrapper -->
<div class="page-wrapper">
<div class="page-inner">
<!-- BEGIN Left Aside -->
<aside class="page-sidebar">
<div class="page-logo" style="width:100%">
<a href="#" class="page-logo-link press-scale-down">
<img src="~/img/dome.png" aria-roledescription="logo" style="width:100%" />
@*<span class="page-logo-text mr-1">IBMS後台管理系統</span>*@
</a>
</div>
<!-- BEGIN PRIMARY NAVIGATION -->
<nav id="js-primary-nav" class="primary-nav" role="navigation">
<div class="nav-filter">
<div class="position-relative">
<input type="text" id="nav_filter_input" placeholder="Filter menu" class="form-control" tabindex="0">
<a href="#" onclick="return false;" class="btn-primary btn-search-close js-waves-off" data-action="toggle" data-class="list-filter-active" data-target=".page-sidebar">
<i class="fal fa-chevron-up"></i>
</a>
</div>
</div>
<!--<div class="info-card">
<img src="img/demo/avatars/avatar-admin.png" class="profile-image rounded-circle" alt="Dr. Codex Lantern">
<div class="info-card-text">
<a href="#" class="d-flex align-items-center text-white">
<span class="text-truncate text-truncate-sm d-inline-block">
Dr. Codex Lantern
</span>
</a>
<span class="d-inline-block text-truncate text-truncate-sm">Toronto, Canada</span>
</div>
<img src="img/card-backgrounds/cover-2-lg.png" class="cover" alt="cover">
<a href="#" onclick="return false;" class="pull-trigger-btn" data-action="toggle" data-class="list-filter-active" data-target=".page-sidebar" data-focus="nav_filter_input">
<i class="fal fa-angle-down"></i>
</a>
</div>-->
<!--
TIP: The menu items are not auto translated. You must have a residing lang file associated with the menu saved inside dist/media/data with reference to each 'data-i18n' attribute.
-->
<ul id="js-nav-menu" class="nav-menu">
<!--<li class="active">
<a href="blank.html" title="Blank Project" data-filter-tags="blank page">
<i class="fal fa-globe"></i>
<span class="nav-link-text" data-i18n="nav.blankpage">Blank Project</span>
</a>
</li>
<li class="nav-title">Navigation Title</li>-->
@if (ViewBag.role.Contains("SystemCategoryIndex") || ViewBag.role.Contains("BuildInfoIndex") || ViewBag.role.Contains("BuildMenuIndex"))
{
<li class="@(ViewData["MainNum"] == "1" ? "active open" : "")">
<a href="#" title="區域資料管理" data-filter-tags="category">
<i class="fal fa-ballot-check"></i>
<span class="nav-link-text" data-i18n="nav.category">區域資料管理</span>
</a>
<ul>
@if (ViewBag.role.Contains("SystemCategoryIndex"))
{
<li class="@(ViewData["MainNum"] == "1" && ViewData["SubNum"] == "1" ? "active" : "")">
<a asp-controller="SystemCategory" asp-action="Index" title=" 系統類別管理" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item"> 系統類別管理</span>
</a>
</li>
}
@if (ViewBag.role.Contains("BuildInfoIndex"))
{
<li class="@(ViewData["MainNum"] == "1" && ViewData["SubNum"] == "2" ? "active" : "")">
<a asp-controller="BuildInfo" asp-action="Index" title="區域設定" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">區域設定</span>
</a>
</li>
}
@if (ViewBag.role.Contains("BuildMenuIndex"))
{
<li class="@(ViewData["MainNum"] == "1" && ViewData["SubNum"] == "3" ? "active" : "")">
<a asp-controller="BuildMenu" asp-action="Index" title="區域選單管理" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">區域選單管理</span>
</a>
</li>
}
</ul>
</li>
}
@if (ViewBag.role.Contains("DeviceImportIndex") || ViewBag.role.Contains("DeviceManageIndex"))
{
<li class="@(ViewData["MainNum"] == "2" ? "active open" : "")">
<a href="#" title="設備管理" data-filter-tags="category">
<i class="fal fa-ballot-check"></i>
<span class="nav-link-text" data-i18n="nav.category">設備管理</span>
</a>
<ul>
@if (ViewBag.role.Contains("DeviceImportIndex"))
{
<li class="@(ViewData["MainNum"] == "2" && ViewData["SubNum"] == "1" ? "active" : "")">
<a asp-controller="DeviceImport" asp-action="Index" title="設備資料匯入" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">設備資料匯入</span>
</a>
</li>
}
@if (ViewBag.role.Contains("DeviceManageIndex"))
{
<li class="@(ViewData["MainNum"] == "2" && ViewData["SubNum"] == "2" ? "active" : "")">
<a asp-controller="DeviceManage" asp-action="Index" title="設備管理" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">設備管理</span>
</a>
</li>
}
</ul>
</li>
}
@if (ViewBag.role.Contains("EmergencySettingIndex")
|| ViewBag.role.Contains("EmergencyGroupingIndex")
|| ViewBag.role.Contains("RescueDeviceFireExtinguisher")
|| ViewBag.role.Contains("RescueDeviceAED"))
{
<li class="@(ViewData["MainNum"] == "3" ? "active open" : "")">
<a href="#" title="緊急應變設定" data-filter-tags="category">
<i class="fal fa-ballot-check"></i>
<span class="nav-link-text" data-i18n="nav.category">緊急應變設定</span>
</a>
<ul>
@if (ViewBag.role.Contains("EmergencySettingIndex"))
{
<li class="@(ViewData["MainNum"] == "3" && ViewData["SubNum"] == "1" ? "active" : "")">
<a asp-controller="EmergencySetting" asp-action="Index" title="步驟設定" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">步驟設定</span>
</a>
</li>
}
@if (ViewBag.role.Contains("EmergencyGroupingIndex"))
{
<li class="@(ViewData["MainNum"] == "3" && ViewData["SubNum"] == "2" ? "active" : "")">
<a asp-controller="EmergencyGrouping" asp-action="Index" title="人員編組設定" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">人員編組設定</span>
</a>
</li>
}
@if (ViewBag.role.Contains("RescueDeviceFireExtinguisher"))
{
<li class="@(ViewData["MainNum"] == "3" && ViewData["SubNum"] == "3" ? "active" : "")">
<a asp-controller="RescueDevice" asp-action="FireExtinguisher" title="滅火器設定" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">滅火器設定</span>
</a>
</li>
}
@if (ViewBag.role.Contains("RescueDeviceAED"))
{
<li class="@(ViewData["MainNum"] == "3" && ViewData["SubNum"] == "4" ? "active" : "")">
<a asp-controller="RescueDevice" asp-action="AED" title="AED裝置設定" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">AED裝置設定</span>
</a>
</li>
}
</ul>
</li>
}
@*@if (ViewBag.role.Contains("EmergencyDeviceMenuIndex")
|| ViewBag.role.Contains("EmergencyContactIndex")
|| ViewBag.role.Contains("EmergencyRecordIndex"))
{
<li class="@(ViewData["MainNum"] == "4" ? "active open" : "")">
<a href="#" title="緊急應變操作" data-filter-tags="category">
<i class="fal fa-ballot-check"></i>
<span class="nav-link-text" data-i18n="nav.category">緊急應變操作</span>
</a>
<ul>
@if (ViewBag.role.Contains("EmergencyDeviceMenuIndex"))
{
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "1" ? "active" : "")">
<a asp-controller="EmergencyDeviceMenu" asp-action="Index" title="設備總覽" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">設備總覽</span>
</a>
</li>
}
@if (ViewBag.role.Contains("EmergencyContactIndex"))
{
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "2" ? "active" : "")">
<a asp-controller="EmergencyContact" asp-action="Index" title="聯絡清單" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">聯絡清單</span>
</a>
</li>
}
@if (ViewBag.role.Contains("EmergencyRecordIndex"))
{
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "3" ? "active" : "")">
<a asp-controller="EmergencyRecord" asp-action="Index" title="紀錄查詢" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">紀錄查詢</span>
</a>
</li>
}
</ul>
</li>
}*@
@if (ViewBag.role.Contains("UserInfoIndex"))
{
<li class="@(ViewData["MainNum"] == "6" ? "active open" : "")">
<a href="#" title="使用者管理" data-filter-tags="category">
<i class="fal fa-ballot-check"></i>
<span class="nav-link-text" data-i18n="nav.category">使用者管理</span>
</a>
<ul>
<li class="@(ViewData["MainNum"] == "6" && ViewData["SubNum"] == "1" ? "active" : "")">
<a asp-controller="UserInfo" asp-action="Index" title="帳號管理" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">帳號管理</span>
</a>
</li>
</ul>
</li>
}
@if (ViewBag.role.Contains("VariableIndex"))
{
<li class="@(ViewData["MainNum"] == "7" ? "active open" : "")">
<a href="#" title="系統變數管理" data-filter-tags="category">
<i class="fal fa-ballot-check"></i>
<span class="nav-link-text" data-i18n="nav.category">系統變數管理</span>
</a>
<ul>
<li class="@(ViewData["MainNum"] == "7" && ViewData["SubNum"] == "1" ? "active" : "")">
<a asp-controller="Variable" asp-action="Index" title="系統變數" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">系統變數</span>
</a>
</li>
</ul>
</li>
}
@*<li class="@(ViewData["MainNum"] == "7" ? "active open" : "")">
<a href="#" title="服務管理" data-filter-tags="category">
<i class="fal fa-ballot-check"></i>
<span class="nav-link-text" data-i18n="nav.category">服務管理</span>
</a>
<ul>
<li class="@(ViewData["MainNum"] == "7" && ViewData["SubNum"] == "1" ? "active" : "")">
<a asp-controller="ServicePlan" asp-action="Index" title="服務計畫" data-filter-tags="utilities disabled item">
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">服務計畫</span>
</a>
</li>
</ul>
</li>*@
</ul>
<div class="filter-message js-filter-message bg-success-600"></div>
</nav>
<!-- END PRIMARY NAVIGATION -->
<!-- NAV FOOTER -->
<!--<div class="nav-footer shadow-top">
<a href="#" onclick="return false;" data-action="toggle" data-class="nav-function-minify" class="hidden-md-down">
<i class="ni ni-chevron-right"></i>
<i class="ni ni-chevron-right"></i>
</a>
<ul class="list-table m-auto nav-footer-buttons">
<li>
<a href="javascript:void(0);" data-toggle="tooltip" data-placement="top" title="Chat logs">
<i class="fal fa-comments"></i>
</a>
</li>
<li>
<a href="javascript:void(0);" data-toggle="tooltip" data-placement="top" title="Support Chat">
<i class="fal fa-life-ring"></i>
</a>
</li>
<li>
<a href="javascript:void(0);" data-toggle="tooltip" data-placement="top" title="Make a call">
<i class="fal fa-phone"></i>
</a>
</li>
</ul>
</div>-->
<!-- END NAV FOOTER -->
</aside>
<!-- END Left Aside -->
<div class="page-content-wrapper">
<!-- BEGIN Page Header -->
<header class="page-header" role="banner">
<!-- we need this logo when user switches to nav-function-top -->
<div class="page-logo">
<a href="#" class="page-logo-link press-scale-down d-flex align-items-center position-relative" data-toggle="modal" data-target="#modal-shortcut">
<img src="~/img/logo.png" alt="SmartAdmin WebApp" aria-roledescription="logo">
<span class="page-logo-text mr-1">SmartAdmin WebApp</span>
<span class="position-absolute text-white opacity-50 small pos-top pos-right mr-2 mt-n2"></span>
<i class="fal fa-angle-down d-inline-block ml-1 fs-lg color-primary-300"></i>
</a>
</div>
<!-- DOC: nav menu layout change shortcut -->
<div class="hidden-md-down dropdown-icon-menu position-relative">
<a href="#" class="header-btn btn js-waves-off" data-action="toggle" data-class="nav-function-hidden" title="Hide Navigation">
<i class="ni ni-menu"></i>
</a>
<ul>
<li>
<a href="#" class="btn js-waves-off" data-action="toggle" data-class="nav-function-minify" title="Minify Navigation">
<i class="ni ni-minify-nav"></i>
</a>
</li>
<li>
<a href="#" class="btn js-waves-off" data-action="toggle" data-class="nav-function-fixed" title="Lock Navigation">
<i class="ni ni-lock-nav"></i>
</a>
</li>
</ul>
</div>
<!-- DOC: mobile button appears during mobile width -->
<div class="hidden-lg-up">
<a href="#" class="header-btn btn press-scale-down" data-action="toggle" data-class="mobile-nav-on">
<i class="ni ni-menu"></i>
</a>
</div>
<!--<div class="search">
<form class="app-forms hidden-xs-down" role="search" action="page_search.html" autocomplete="off">
<input type="text" id="search-field" placeholder="Search for anything" class="form-control" tabindex="1">
<a href="#" onclick="return false;" class="btn-danger btn-search-close js-waves-off d-none" data-action="toggle" data-class="mobile-search-on">
<i class="fal fa-times"></i>
</a>
</form>
</div>-->
<h1 class="subheader-title">IBMS後台管理系統</h1>
<div class="ml-auto d-flex">
<!-- activate app search icon (mobile) -->
<div class="hidden-sm-up">
<a href="#" class="header-icon" data-action="toggle" data-class="mobile-search-on" data-focus="search-field" title="Search">
<i class="fal fa-search"></i>
</a>
</div>
<!-- app settings -->
<div class="hidden-md-down">
<a href="#" class="header-icon" data-toggle="modal" data-target=".js-modal-settings" style="display:none">
<i class="fal fa-cog"></i>
</a>
</div>
<!-- app message -->
<a href="#" class="header-icon" data-toggle="modal" data-target="" style="display:none">
<i class="fal fa-search"></i>
<span class="badge badge-icon">!</span>
</a>
<!-- app notification -->
<div>
<a href="#" class="header-icon" data-toggle="dropdown" title="You got 11 notifications" style="display:none">
<i class="fal fa-bell"></i>
<span class="badge badge-icon">11</span>
</a>
<div class="dropdown-menu dropdown-menu-animated dropdown-xl">
<div class="dropdown-header bg-trans-gradient d-flex justify-content-center align-items-center rounded-top mb-2">
<h4 class="m-0 text-center color-white">
11 New
<small class="mb-0 opacity-80">User Notifications</small>
</h4>
</div>
<ul class="nav nav-tabs nav-tabs-clean" role="tablist">
<li class="nav-item">
<a class="nav-link px-4 fs-md js-waves-on fw-500" data-toggle="tab" href="#tab-messages" data-i18n="drpdwn.messages">Messages</a>
</li>
<li class="nav-item">
<a class="nav-link px-4 fs-md js-waves-on fw-500" data-toggle="tab" href="#tab-feeds" data-i18n="drpdwn.feeds">Feeds</a>
</li>
<li class="nav-item">
<a class="nav-link px-4 fs-md js-waves-on fw-500" data-toggle="tab" href="#tab-events" data-i18n="drpdwn.events">Events</a>
</li>
</ul>
<div class="tab-content tab-notification">
<div class="tab-pane active p-3 text-center">
<h5 class="mt-4 pt-4 fw-500">
<span class="d-block fa-3x pb-4 text-muted">
<i class="ni ni-arrow-up text-gradient opacity-70"></i>
</span> Select a tab above to activate
<small class="mt-3 fs-b fw-400 text-muted">
This blank page message helps protect your privacy, or you can show the first message here automatically through
<a href="#">settings page</a>
</small>
</h5>
</div>
<div class="tab-pane" id="tab-messages" role="tabpanel">
<div class="custom-scroll h-100">
<ul class="notification">
<li class="unread">
<a href="#" class="d-flex align-items-center">
<span class="status mr-2">
<span class="profile-image rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-c.png')"></span>
</span>
<span class="d-flex flex-column flex-1 ml-1">
<span class="name">Melissa Ayre <span class="badge badge-primary fw-n position-absolute pos-top pos-right mt-1">INBOX</span></span>
<span class="msg-a fs-sm">Re: New security codes</span>
<span class="msg-b fs-xs">Hello again and thanks for being part...</span>
<span class="fs-nano text-muted mt-1">56 seconds ago</span>
</span>
</a>
</li>
<li class="unread">
<a href="#" class="d-flex align-items-center">
<span class="status mr-2">
<span class="profile-image rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-a.png')"></span>
</span>
<span class="d-flex flex-column flex-1 ml-1">
<span class="name">Adison Lee</span>
<span class="msg-a fs-sm">Msed quia non numquam eius</span>
<span class="fs-nano text-muted mt-1">2 minutes ago</span>
</span>
</a>
</li>
<li>
<a href="#" class="d-flex align-items-center">
<span class="status status-success mr-2">
<span class="profile-image rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-b.png')"></span>
</span>
<span class="d-flex flex-column flex-1 ml-1">
<span class="name">Oliver Kopyuv</span>
<span class="msg-a fs-sm">Msed quia non numquam eius</span>
<span class="fs-nano text-muted mt-1">3 days ago</span>
</span>
</a>
</li>
<li>
<a href="#" class="d-flex align-items-center">
<span class="status status-warning mr-2">
<span class="profile-image rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-e.png')"></span>
</span>
<span class="d-flex flex-column flex-1 ml-1">
<span class="name">Dr. John Cook PhD</span>
<span class="msg-a fs-sm">Msed quia non numquam eius</span>
<span class="fs-nano text-muted mt-1">2 weeks ago</span>
</span>
</a>
</li>
<li>
<a href="#" class="d-flex align-items-center">
<span class="status status-success mr-2">
<!-- <img src="img/demo/avatars/avatar-m.png" data-src="img/demo/avatars/avatar-h.png" class="profile-image rounded-circle" alt="Sarah McBrook" /> -->
<span class="profile-image rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-h.png')"></span>
</span>
<span class="d-flex flex-column flex-1 ml-1">
<span class="name">Sarah McBrook</span>
<span class="msg-a fs-sm">Msed quia non numquam eius</span>
<span class="fs-nano text-muted mt-1">3 weeks ago</span>
</span>
</a>
</li>
<li>
<a href="#" class="d-flex align-items-center">
<span class="status status-success mr-2">
<span class="profile-image rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-m.png')"></span>
</span>
<span class="d-flex flex-column flex-1 ml-1">
<span class="name">Anothony Bezyeth</span>
<span class="msg-a fs-sm">Msed quia non numquam eius</span>
<span class="fs-nano text-muted mt-1">one month ago</span>
</span>
</a>
</li>
<li>
<a href="#" class="d-flex align-items-center">
<span class="status status-danger mr-2">
<span class="profile-image rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-j.png')"></span>
</span>
<span class="d-flex flex-column flex-1 ml-1">
<span class="name">Lisa Hatchensen</span>
<span class="msg-a fs-sm">Msed quia non numquam eius</span>
<span class="fs-nano text-muted mt-1">one year ago</span>
</span>
</a>
</li>
</ul>
</div>
</div>
<div class="tab-pane" id="tab-feeds" role="tabpanel">
<div class="custom-scroll h-100">
<ul class="notification">
<li class="unread">
<div class="d-flex align-items-center show-child-on-hover">
<span class="d-flex flex-column flex-1">
<span class="name d-flex align-items-center">Administrator <span class="badge badge-success fw-n ml-1">UPDATE</span></span>
<span class="msg-a fs-sm">
System updated to version <strong>4.5.1</strong> <a href="docs_buildnotes.html">(patch notes)</a>
</span>
<span class="fs-nano text-muted mt-1">5 mins ago</span>
</span>
<div class="show-on-hover-parent position-absolute pos-right pos-bottom p-3">
<a href="#" class="text-muted" title="delete"><i class="fal fa-trash-alt"></i></a>
</div>
</div>
</li>
<li>
<div class="d-flex align-items-center show-child-on-hover">
<div class="d-flex flex-column flex-1">
<span class="name">
Adison Lee <span class="fw-300 d-inline">replied to your video <a href="#" class="fw-400"> Cancer Drug</a> </span>
</span>
<span class="msg-a fs-sm mt-2">Bring to the table win-win survival strategies to ensure proactive domination. At the end of the day...</span>
<span class="fs-nano text-muted mt-1">10 minutes ago</span>
</div>
<div class="show-on-hover-parent position-absolute pos-right pos-bottom p-3">
<a href="#" class="text-muted" title="delete"><i class="fal fa-trash-alt"></i></a>
</div>
</div>
</li>
<li>
<div class="d-flex align-items-center show-child-on-hover">
<!--<img src="img/demo/avatars/avatar-m.png" data-src="img/demo/avatars/avatar-k.png" class="profile-image rounded-circle" alt="k" />-->
<div class="d-flex flex-column flex-1">
<span class="name">
Troy Norman'<span class="fw-300">s new connections</span>
</span>
<div class="fs-sm d-flex align-items-center mt-2">
<span class="profile-image-md mr-1 rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-a.png'); background-size: cover;"></span>
<span class="profile-image-md mr-1 rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-b.png'); background-size: cover;"></span>
<span class="profile-image-md mr-1 rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-c.png'); background-size: cover;"></span>
<span class="profile-image-md mr-1 rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-e.png'); background-size: cover;"></span>
<div data-hasmore="+3" class="rounded-circle profile-image-md mr-1">
<span class="profile-image-md mr-1 rounded-circle d-inline-block" style="background-image:url('img/demo/avatars/avatar-h.png'); background-size: cover;"></span>
</div>
</div>
<span class="fs-nano text-muted mt-1">55 minutes ago</span>
</div>
<div class="show-on-hover-parent position-absolute pos-right pos-bottom p-3">
<a href="#" class="text-muted" title="delete"><i class="fal fa-trash-alt"></i></a>
</div>
</div>
</li>
<li>
<div class="d-flex align-items-center show-child-on-hover">
<!--<img src="img/demo/avatars/avatar-m.png" data-src="img/demo/avatars/avatar-e.png" class="profile-image-sm rounded-circle align-self-start mt-1" alt="k" />-->
<div class="d-flex flex-column flex-1">
<span class="name">Dr John Cook <span class="fw-300">sent a <span class="text-danger">new signal</span></span></span>
<span class="msg-a fs-sm mt-2">Nanotechnology immersion along the information highway will close the loop on focusing solely on the bottom line.</span>
<span class="fs-nano text-muted mt-1">10 minutes ago</span>
</div>
<div class="show-on-hover-parent position-absolute pos-right pos-bottom p-3">
<a href="#" class="text-muted" title="delete"><i class="fal fa-trash-alt"></i></a>
</div>
</div>
</li>
<li>
<div class="d-flex align-items-center show-child-on-hover">
<div class="d-flex flex-column flex-1">
<span class="name">Lab Images <span class="fw-300">were updated!</span></span>
<div class="fs-sm d-flex align-items-center mt-1">
<a href="#" class="mr-1 mt-1" title="Cell A-0012">
<span class="d-block img-share" style="background-image:url('img/thumbs/pic-7.png'); background-size: cover;"></span>
</a>
<a href="#" class="mr-1 mt-1" title="Patient A-473 saliva">
<span class="d-block img-share" style="background-image:url('img/thumbs/pic-8.png'); background-size: cover;"></span>
</a>
<a href="#" class="mr-1 mt-1" title="Patient A-473 blood cells">
<span class="d-block img-share" style="background-image:url('img/thumbs/pic-11.png'); background-size: cover;"></span>
</a>
<a href="#" class="mr-1 mt-1" title="Patient A-473 Membrane O.C">
<span class="d-block img-share" style="background-image:url('img/thumbs/pic-12.png'); background-size: cover;"></span>
</a>
</div>
<span class="fs-nano text-muted mt-1">55 minutes ago</span>
</div>
<div class="show-on-hover-parent position-absolute pos-right pos-bottom p-3">
<a href="#" class="text-muted" title="delete"><i class="fal fa-trash-alt"></i></a>
</div>
</div>
</li>
<li>
<div class="d-flex align-items-center show-child-on-hover">
<!--<img src="img/demo/avatars/avatar-m.png" data-src="img/demo/avatars/avatar-h.png" class="profile-image rounded-circle align-self-start mt-1" alt="k" />-->
<div class="d-flex flex-column flex-1">
<div class="name mb-2">
Lisa Lamar<span class="fw-300"> updated project</span>
</div>
<div class="row fs-b fw-300">
<div class="col text-left">
Progress
</div>
<div class="col text-right fw-500">
45%
</div>
</div>
<div class="progress progress-sm d-flex mt-1">
<span class="progress-bar bg-primary-500 progress-bar-striped" role="progressbar" style="width: 45%" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100"></span>
</div>
<span class="fs-nano text-muted mt-1">2 hrs ago</span>
<div class="show-on-hover-parent position-absolute pos-right pos-bottom p-3">
<a href="#" class="text-muted" title="delete"><i class="fal fa-trash-alt"></i></a>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="tab-pane" id="tab-events" role="tabpanel">
<div class="d-flex flex-column h-100">
<div class="h-auto">
<table class="table table-bordered table-calendar m-0 w-100 h-100 border-0">
<tr>
<th colspan="7" class="pt-3 pb-2 pl-3 pr-3 text-center">
<div class="js-get-date h5 mb-2">[your date here]</div>
</th>
</tr>
<tr class="text-center">
<th>Sun</th>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
</tr>
<tr>
<td class="text-muted bg-faded">30</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td><i class="fal fa-birthday-cake mt-1 ml-1 position-absolute pos-left pos-top text-primary"></i> 6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
<td class="bg-primary-300 pattern-0">10</td>
<td>11</td>
<td>12</td>
<td>13</td>
</tr>
<tr>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
</tr>
<tr>
<td>28</td>
<td>29</td>
<td>30</td>
<td>31</td>
<td class="text-muted bg-faded">1</td>
<td class="text-muted bg-faded">2</td>
<td class="text-muted bg-faded">3</td>
</tr>
</table>
</div>
<div class="flex-1 custom-scroll">
<div class="p-2">
<div class="d-flex align-items-center text-left mb-3">
<div class="width-5 fw-300 text-primary l-h-n mr-1 align-self-start fs-xxl">
15
</div>
<div class="flex-1">
<div class="d-flex flex-column">
<span class="l-h-n fs-md fw-500 opacity-70">
October 2020
</span>
<span class="l-h-n fs-nano fw-400 text-secondary">
Friday
</span>
</div>
<div class="mt-3">
<p>
<strong>2:30PM</strong> - Doctor's appointment
</p>
<p>
<strong>3:30PM</strong> - Report overview
</p>
<p>
<strong>4:30PM</strong> - Meeting with Donnah V.
</p>
<p>
<strong>5:30PM</strong> - Late Lunch
</p>
<p>
<strong>6:30PM</strong> - Report Compression
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="py-2 px-3 bg-faded d-block rounded-bottom text-right border-faded border-bottom-0 border-right-0 border-left-0">
<a href="#" class="fs-xs fw-500 ml-auto">view all notifications</a>
</div>
</div>
</div>
<!-- app user menu -->
<div>
<a href="#" data-toggle="dropdown" title="drlantern@gotbootstrap.com" class="header-icon d-flex align-items-center justify-content-center ml-2">
<img src="~/img/demo/avatars/avatar-admin.png" class="profile-image rounded-circle" alt="Dr. Codex Lantern">
<!-- you can also add username next to the avatar with the codes below:
<span class="ml-1 mr-1 text-truncate text-truncate-header hidden-xs-down">Me</span>
<i class="ni ni-chevron-down hidden-xs-down"></i> -->
</a>
<div class="dropdown-menu dropdown-menu-animated dropdown-lg">
<div class="dropdown-header bg-trans-gradient d-flex flex-row py-4 rounded-top">
<div class="d-flex flex-row align-items-center mt-1 mb-1 color-white">
<span class="mr-2"> <img src="~/img/demo/avatars/avatar-admin.png" class="rounded-circle profile-image" alt="Dr. Codex Lantern"> </span>
<div class="info-card-text">
<div class="fs-lg text-truncate text-truncate-lg">@ViewBag.myUserInfo.Full_name</div>
<span class="text-truncate text-truncate-md opacity-80">@ViewBag.myUserInfo.Email</span>
</div>
</div>
</div>
<div class="dropdown-divider m-0"></div>
<a href="javascript:void(0);" id="btn-personal-info" class="dropdown-item"> <span data-i18n="drpdwn.settings">個人資料</span> </a>
<a href="javascript:void(0);" id="btn-change-password" class="dropdown-item"> <span data-i18n="drpdwn.settings">密碼修改</span> </a>
<div class="dropdown-divider m-0"></div>
<a href="#" class="dropdown-item" data-action="app-fullscreen"> <span data-i18n="drpdwn.fullscreen">Fullscreen</span> <i class="float-right text-muted fw-n">F11</i> </a> <a href="#" class="dropdown-item" data-action="app-print"> <span data-i18n="drpdwn.print">Print</span> <i class="float-right text-muted fw-n">Ctrl + P</i> </a>
<div class="dropdown-divider m-0"></div>
<a class="dropdown-item fw-500 pt-3 pb-3" asp-controller="Login" asp-action="SignOut"> <span data-i18n="drpdwn.page-logout">登出</span> <span class="float-right fw-n">&commat;fic</span> </a>
</div>
</div>
</div>
</header>
<!-- END Page Header -->
<!-- BEGIN Page Content -->
<!-- the #js-page-content id is needed for some plugins to initialize -->
<main id="js-page-content" role="main" class="page-content">
@RenderBody()
</main>
<!-- BEGIN Page Footer -->
<footer class="page-footer" role="contentinfo">
@*<div class="d-flex align-items-center flex-1 text-muted">
<span class="hidden-md-down fw-700">2020 © Rage by&nbsp;<a href='https://www.rage.com.tw' class='text-primary fw-500' title='rage.com.tw' target='_blank'>rage.com.tw</a></span>
</div>
<div>
<ul class="list-table m-0">
<li><a href="intel_introduction.html" class="text-secondary fw-700">About</a></li>
<li class="pl-3"><a href="info_app_licensing.html" class="text-secondary fw-700">License</a></li>
<li class="pl-3"><a href="info_app_docs.html" class="text-secondary fw-700">Documentation</a></li>
</ul>
</div>*@
</footer>
<!-- END Page Footer -->
<!-- BEGIN Color profile -->
<!-- this area is hidden and will not be seen on screens or screen readers -->
<!-- we use this only for CSS color refernce for JS stuff -->
<p id="js-color-profile" class="d-none">
<span class="color-primary-50"></span>
<span class="color-primary-100"></span>
<span class="color-primary-200"></span>
<span class="color-primary-300"></span>
<span class="color-primary-400"></span>
<span class="color-primary-500"></span>
<span class="color-primary-600"></span>
<span class="color-primary-700"></span>
<span class="color-primary-800"></span>
<span class="color-primary-900"></span>
<span class="color-info-50"></span>
<span class="color-info-100"></span>
<span class="color-info-200"></span>
<span class="color-info-300"></span>
<span class="color-info-400"></span>
<span class="color-info-500"></span>
<span class="color-info-600"></span>
<span class="color-info-700"></span>
<span class="color-info-800"></span>
<span class="color-info-900"></span>
<span class="color-danger-50"></span>
<span class="color-danger-100"></span>
<span class="color-danger-200"></span>
<span class="color-danger-300"></span>
<span class="color-danger-400"></span>
<span class="color-danger-500"></span>
<span class="color-danger-600"></span>
<span class="color-danger-700"></span>
<span class="color-danger-800"></span>
<span class="color-danger-900"></span>
<span class="color-warning-50"></span>
<span class="color-warning-100"></span>
<span class="color-warning-200"></span>
<span class="color-warning-300"></span>
<span class="color-warning-400"></span>
<span class="color-warning-500"></span>
<span class="color-warning-600"></span>
<span class="color-warning-700"></span>
<span class="color-warning-800"></span>
<span class="color-warning-900"></span>
<span class="color-success-50"></span>
<span class="color-success-100"></span>
<span class="color-success-200"></span>
<span class="color-success-300"></span>
<span class="color-success-400"></span>
<span class="color-success-500"></span>
<span class="color-success-600"></span>
<span class="color-success-700"></span>
<span class="color-success-800"></span>
<span class="color-success-900"></span>
<span class="color-fusion-50"></span>
<span class="color-fusion-100"></span>
<span class="color-fusion-200"></span>
<span class="color-fusion-300"></span>
<span class="color-fusion-400"></span>
<span class="color-fusion-500"></span>
<span class="color-fusion-600"></span>
<span class="color-fusion-700"></span>
<span class="color-fusion-800"></span>
<span class="color-fusion-900"></span>
</p>
<!-- END Color profile -->
</div>
</div>
</div>
<!-- END Page Wrapper -->
<!-- Site wrapper -->
<!-- /.wrapper -->
<!-- 個人資料 -->
<div class="modal" tabindex="-1" id="personal-info-modal" role="dialog" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">個人資料</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<form class="personal-info-form" id="personal-info-form">
<div class="form-row mb-3">
<div class="form-group col-md-12">
<label for="name_modal">
<font class="text-danger">*</font>姓名:
</label>
<input type="text" class="form-control" id="name_modal" name="name_modal" autocomplete="off" />
</div>
</div>
<div class="form-row mb-3">
<div class="form-group col-md-12">
<label for="account_modal">
帳號:
</label>
<input type="text" class="form-control" id="account_modal" name="account_modal" disabled>
</div>
</div>
<div class="form-row mb-3">
<div class="form-group col-md-12">
<label for="email_modal">
電子信箱:
</label>
<input type="email" class="form-control" id="email_modal" name="email_modal" autocomplete="off">
</div>
</div>
<div class="form-row mb-3">
<div class="form-group col-md-12">
<label for="phone_modal">
電話:
</label>
<input type="text" class="form-control" id="phone_modal" name="phone_modal" autocomplete="off">
</div>
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary btn-save" onclick="SavePersonalInfo()">儲存</button>
</div>
</div>
</div>
</div>
<!-- /.個人資料 -->
<!-- 變更密碼 -->
<div class="modal" tabindex="-1" id="change-password-modal" role="dialog" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">變更密碼</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<form class="change-password-form" id="change-password-form">
<div class="form-row mb-3">
<div class="form-group col-md-12">
<label for="old_password_modal">
<font class="text-danger">*</font>舊密碼:
</label>
<input type="password" class="form-control" id="old_password_id_modal" name="old_password_modal" autocomplete="off" />
</div>
</div>
<div class="form-row mb-3">
<div class="form-group col-md-12">
<label for="new_password_modal">
<font class="text-danger">*</font>新密碼:
</label>
<input type="password" class="form-control" id="new_password_id_modal" name="new_password_modal" autocomplete="off">
</div>
</div>
<div class="form-row mb-3">
<div class="form-group col-md-12">
<label for="again_password_modal">
<font class="text-danger">*</font>確認新密碼:
</label>
<input type="password" class="form-control" id="again_password_id_modal" name="again_password_modal" autocomplete="off" minlength="6" maxlength="12" required>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary btn-save" onclick="ChangePassword()">儲存</button>
</div>
</div>
</div>
</div>
<!-- /.變更密碼 -->
<!--Base JS-->
<script src="~/js/vendors.bundle.js" asp-append-version="true"></script>
<script src="~/js/app.bundle.js" asp-append-version="true"></script>
<!-- JQuery Validate -->
<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>
<!-- dataTables -->
<script src="~/js/datagrid/datatables/datatables.bundle.js"></script>
<!-- SweetAlert -->
<script src="~/js/notifications/sweetalert2/sweetalert2.bundle.js"></script>
<script src="~/js/notifications/toastr/toastr.js"></script>
<!--Toast-->
<script src="~/js/toast.js"></script>
<!-- Select2 JS -->
<script src="~/js/formplugins/select2/select2.bundle.js"></script>
<!-- table2excel -->
@*<script src="~/js/jquery.table2excel.min.js"></script>*@
<!--HighCharts.js-->
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<!-- Custome JS -->
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="~/js/image.zoom.js" asp-append-version="true"></script>
<!-- datepicker -->
<script type="text/javascript" src="~/js/moment/moment.min.js"></script>
<script type="text/javascript" src="~/js/daterangepicker/daterangepicker.js"></script>
@*各頁面的JavaScript*@
@RenderSection("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

View File

@ -0,0 +1,790 @@
@{
ViewData["MainNum"] = "1";
ViewData["SubNum"] = "1";
ViewData["Title"] = "設備類別管理";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">設備系統基本資料</a></li>
<li class="breadcrumb-item active">設備類別管理</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-xl-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<ul class="nav nav-tabs" id="tabs" role="tablist">
<li class="nav-item"><a class="nav-link active" data-toggle="tab" href="#tab-system-main" role="tab"><span class="hidden-sm-down ml-1">系統大類</span></a></li>
<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#tab-system-sub" role="tab"><span class="hidden-sm-down ml-1">系統小類</span></a></li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane fade show active" id="tab-system-main" role="tabpanel" aria-labelledby="tab-system-main">
@Html.Partial("_SystemMain")
</div>
<div class="tab-pane fade" id="tab-system-sub" role="tabpanel" aria-labelledby="tab-system-sub">
@Html.Partial("_SystemSub")
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var systemMainTable, systemSubTable, deviceTable;
var selected_system_main_guid = "";
var selected_system_main_guid_top_name = "";
var selected_system_sub_guid = "";
var selected_system_device_item_guid = "";
//#region 系統大類 document ready
$(function () {
//#region 系統大類 DataTable
systemMainTable = $("#system_main_table").DataTable({
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "full_name"
},
{
"data": "code"
},
{
"data": "created_at"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-guid', data.main_system_guid);
},
//"order": [[2, "desc"]],
"ajax": {
"url": "/SystemCategory/SystemMainList",
"type": "POST",
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
//系統小類上方選單
$("#system-main-list").empty();
$.each(data, function (key, value) {
if (key == 0) {
selected_system_main_guid_top_name = value.full_name;
$("#system-main-list").append(`<button type="button" class="btn btn-success waves-effect waves-themed ml-2 mb-2 btn-station" id="${value.main_system_guid}" onclick="clickSystemMain('${value.main_system_guid}')">${value.full_name}</button>`);
$(`#${value.main_system_guid}`).trigger("click");
}
else {
$("#system-main-list").append(`<button type="button" class="btn btn-outline-success waves-effect waves-themed ml-2 mb-2 btn-station" id="${value.main_system_guid}" onclick="clickSystemMain('${value.main_system_guid}')">${value.full_name}</button>`);
}
});
return data;
}
}
});
//#endregion
//#region 編輯系統大類
$('#system_main_table').on("click", "button.edit-btn", function () {
$("#system-main-modal .modal-title").html("系統大類資料 - 編輯");
selected_system_main_guid = $(this).parents('tr').attr('data-guid');
//取得單一系統大類
var url = "/SystemCategory/GetOneSystemMain";
var send_data = {
guid: selected_system_main_guid
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
$("#system_main_name_modal").val(rel.data.full_name);
$("#system_main_code_modal").val(rel.data.code);
$("#system-main-modal").modal();
}
}, 'json');
});
//#endregion
//#region 刪除系統大類
$('#system_main_table').on("click", "button.del-btn", function () {
selected_system_main_guid = $(this).parents('tr').attr('data-guid');
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/SystemCategory/DeleteOneSystemMain";
var send_data = {
Guid: selected_system_main_guid
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else if (rel.code == "9997") {
var htnl = rel.msg + "<br>" + rel.data
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: htnl,
});
}
else {
toast_warning(rel.msg);
}
}
else {
toast_ok(rel.msg);
systemMainTable.ajax.reload(null, false);
}
}, 'json');
}
});
});
//#endregion
});
//#endregion
//#region 新增系統大類資料
function AddSystemMain() {
selected_system_main_guid = "";
SystemMainValidate.resetForm();
$("#system-main-modal .modal-title").html("系統大類資料 - 新增");
$("#system-main-form").trigger("reset");
$("#system-main-modal").modal();
}
//#endregion
//#region 系統大類表單驗證
var SystemMainValidate = $("#system-main-form").validate({
rules: {
system_main_name_modal: {
required: true,
maxlength: 50,
filterspace: true
},
system_main_code_modal: {
required: true,
maxlength: 50,
filterspace: true
}
}
});
//#endregion
//#region 儲存系統大類資料
function SaveSystemMain() {
if ($("#system-main-form").valid()) {
$("#save-system-main-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
var url = "/SystemCategory/SaveSystemMain";
var send_data = {
Main_system_guid: selected_system_main_guid,
Full_name: $('#system_main_name_modal').val(),
Code: $('#system_main_code_modal').val()
}
$.post(url, send_data, function (rel) {
$("#save-system-main-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);
systemMainTable.ajax.reload(null, false);
$('#system-main-modal').modal('hide');
return;
}
}, 'json')
.fail(function (xhr, status, error) {
$("#save-system-main-btn").html('確定').attr("disabled", false);
});
}
}
//#endregion
</script>
<script>
//#region 系統小類 document ready
$(function () {
$('#submenucard').hide();
//#region 系統小類 DataTable
systemSubTable = $("#system_sub_table").DataTable({
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": null,
"render": function (data, type, row, meta) {
return selected_system_main_guid_top_name;
}
},
{
"data": "full_name"
},
{
"data": "created_at"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-guid', data.sub_system_guid);
},
//"order": [[2, "desc"]],
"ajax": {
"url": "/SystemCategory/SystemSubList",
"type": "POST",
"data": function (d) {
d.Main_system_guid = selected_system_main_guid
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
//#endregion
//#region 設備項目 DataTable
deviceTable = $("#device_sub_table").DataTable({
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "full_name"
},
{
"data": "points"
},
{
"data": "unit"
},
{
"data": "is_show"
},
{
"data": "is_show_riserDiagram"
},
{
"data": "is_controll"
},
{
"data": "is_bool"
},
{
"data": null,
"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-guid', data.device_item_guid);
},
//"order": [[2, "desc"]],
"ajax": {
"url": "/SystemCategory/DeviceItemTable",
"type": "POST",
"data": function (d) {
d.sub_system_guid = selected_system_sub_guid
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
$.each(data, function (index, rel) {
if (rel.is_show == 0) {
rel.is_show = "否"
} else {
rel.is_show = "是"
}
if (rel.is_show_riserDiagram == 0) {
rel.is_show_riserDiagram = "否"
} else {
rel.is_show_riserDiagram = "是"
}
if (rel.is_controll == 0) {
rel.is_controll = "否"
} else {
rel.is_controll = "是"
}
if (rel.is_bool == 0) {
rel.is_bool = "否"
} else {
rel.is_bool = "是"
}
});
return data;
}
}
});
//#endregion
//#region 編輯系統小類
$('#system_sub_table').on("click", "button.edit-btn", function () {
$("#system-sub-modal .modal-title").html("系統小類資料 - 編輯");
selected_system_sub_guid = $(this).parents('tr').attr('data-guid');
//取得單一系統小類
var url = "/SystemCategory/GetOneSystemSub";
var send_data = {
guid: selected_system_sub_guid
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
$("#system_main_name").html(selected_system_main_guid_top_name)
$("#system_sub_name_modal").val(rel.data.full_name);
$("#system-sub-modal").modal();
}
}, 'json');
});
//#endregion
//#region 刪除系統小類
$('#system_sub_table').on("click", "button.del-btn", function () {
selected_system_sub_guid = $(this).parents('tr').attr('data-guid');
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/SystemCategory/DeleteOneSystemSub";
var send_data = {
Guid: selected_system_sub_guid
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else if (rel.code == "9997") {
var htnl = rel.msg + "<br>" + rel.data
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: htnl,
});
}
else {
toast_warning(rel.msg);
}
return;
}
else {
toast_ok(rel.msg);
$('#submenucard').hide();
systemSubTable.ajax.reload(null, false);
return;
}
}, 'json');
}
});
});
//#endregion
});
//#endregion
//#region 系統小類畫面 - 選擇系統大類
function clickSystemMain(guid) {
selected_system_main_guid = guid;
selected_system_main_guid_top_name = $(`#${guid}`).text();
if ($('#system-main-list').find('.btn-station').hasClass("btn-success")) {
$('#system-main-list').find('.btn-station').removeClass("btn-success").addClass("btn-outline-success");
}
$(`#${guid}`).removeClass("btn-outline-success").addClass("btn-success");
$('#submenucard').hide();
systemSubTable.ajax.reload(null, false);
}
//#endregion
//#region 新增系統小類資料
function AddSystemSub() {
selected_system_sub_guid = "";
SystemSubValidate.resetForm();
$("#system-sub-modal .modal-title").html("系統小類資料 - 新增");
$("#system-sub-form").trigger("reset");
$("#system_main_name").html(selected_system_main_guid_top_name)
$("#system-sub-modal").modal();
}
//#endregion
//#region 系統小類表單驗證
var SystemSubValidate = $("#system-sub-form").validate({
rules: {
system_sub_name_modal: {
required: true,
maxlength: 50,
filterspace: true
},
}
});
//#endregion
//#region 儲存系統小類資料
function SaveSystemSub() {
if ($("#system-sub-form").valid()) {
$("#save-system-sub-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
var url = "/SystemCategory/SaveSystemSub";
var send_data = {
Sub_system_guid: selected_system_sub_guid,
Main_system_guid: selected_system_main_guid,
Full_name: $('#system_sub_name_modal').val(),
}
$.post(url, send_data, function (rel) {
$("#save-system-sub-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);
$('#submenucard').hide();
systemSubTable.ajax.reload(null, false);
$('#system-sub-modal').modal('hide');
return;
}
}, 'json')
.fail(function (xhr, status, error) {
$("#save-system-sub-btn").html('確定').attr("disabled", false);
});
}
}
//#endregion
//#region 新增設備項目
function Adddevice_item() {
//SubDeviceItemValidate.resetForm();
selected_system_device_item_guid = "";
$("#device-sub-modal .modal-title").html("設備項目 - 新增");
$("#device-item-sub-form").trigger("reset");
$("#device-sub-modal").modal();
}
//#endregion
$('#system_sub_table').on("click", "tbody>tr", function () {
$(this).parents().find('tr').css('background-color', '#fff');
$(this).css('background-color', '#67B4AC');
selected_system_sub_guid = $(this).attr('data-guid');
deviceTable.ajax.reload();
$('#submenucard').show();
});
//#region 設備項目表單驗證
$("#device-item-sub-form").validate({
rules: {
device_sub_name_modal: {
required: true,
maxlength: 50
},
device_sub_points_modal: {
required: true,
maxlength: 20
}
}
});
//#endregion
//#region 儲存設備項目
function Savedevice_item() {
if ($("#device-item-sub-form").valid()) {
$("#save-device-item-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
var uurl = "/SystemCategory/HaveSamePoints";
var ssend_data = {
sub_system_guid: selected_system_sub_guid,
points: $('#device_sub_points_modal').val(),
device_item_guid: selected_system_device_item_guid,
}
$.post(uurl, ssend_data, function (rel) {
if (rel.code != "0000") {
$("#save-device-item-btn").html('確定').attr("disabled", false);
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
if (rel.data) {
toast_warning("點位名稱已存在");
$("#save-device-item-btn").html('確定').attr("disabled", false);
}
else {
var url = "/SystemCategory/Savedevice_item";
var send_data = {
device_item_guid: selected_system_device_item_guid,
sub_system_guid: selected_system_sub_guid,
full_name: $('#device_sub_name_modal').val(),
points: $('#device_sub_points_modal').val(),
unit: $('#device_sub_unit_modal').val(),
is_show: $('input[name="is_show"]:checked').val(),
is_show_riserDiagram: $('input[name="is_show_riserDiagram"]:checked').val(),
is_controll: $('input[name="is_controll"]:checked').val(),
is_bool: $('input[name="is_bool"]:checked').val(),
}
$.post(url, send_data, function (rel) {
$("#save-device-item-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);
deviceTable.ajax.reload(null, false);
$('#device-sub-modal').modal('hide');
return;
}
}, 'json')
.fail(function (xhr, status, error) {
$("#save-device-item-btn").html('確定').attr("disabled", false);
});
}
}
}, 'json')
.fail(function (xhr, status, error) {
$("#save-device-item-btn").html('確定').attr("disabled", false);
});
}
}
//#endregion
//#region 編輯設備項目
$('#device_sub_table').on("click", "button.edit-btn", function () {
$("#device-sub-modal .modal-title").html("設備項目 - 編輯");
selected_system_device_item_guid = $(this).parents('tr').attr('data-guid');
//取得單一系統小類
var url = "/SystemCategory/GetOneDeviceItem";
var send_data = {
guid: selected_system_device_item_guid
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
$("#device-item-sub-form").trigger("reset");
$("#device_sub_name_modal").val(rel.data.full_name);
$("#device_sub_points_modal").val(rel.data.points);
$("#device_sub_unit_modal").val(rel.data.unit);
$("input[name='is_show'][value='" + rel.data.is_show + "']").prop("checked", true);
$("input[name='is_show_riserDiagram'][value='" + rel.data.is_show_riserDiagram + "']").prop("checked", true);
$("input[name='is_controll'][value='" + rel.data.is_controll + "']").prop("checked", true);
$("input[name='is_bool'][value='" + rel.data.is_bool + "']").prop("checked", true);
$("#device-sub-modal").modal();
}
}, 'json');
});
//#endregion
//#region 刪除設備項目
$('#device_sub_table').on("click", "button.del-btn", function () {
selected_system_device_item_guid = $(this).parents('tr').attr('data-guid');
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var uurl = "/SystemCategory/CheckCanDelete";
var ssend_data = {
subguid: selected_system_sub_guid,
guid: selected_system_device_item_guid
}
$.post(uurl, ssend_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
if (rel.data.delete) {
var htnl = "以下點位使用中,故無法刪除<br>" + rel.data.reason
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: htnl,
});
} else {
var url = "/SystemCategory/DeleteOneSystemSubDeviceItem";
var send_data = {
guid: selected_system_device_item_guid
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else {
toast_warning(rel.msg);
}
return;
}
else {
toast_ok(rel.msg);
deviceTable.ajax.reload(null, false);
return;
}
}, 'json');
}
}
});
}
});
});
//#endregion
</script>
}

View File

@ -0,0 +1,58 @@
<div class="row mb-3">
<div class="col-12 d-flex justify-content-end">
<a href="javascript:;" class="btn btn-success waves-effect waves-themed mb-3" id="addSystemMain-btn" onclick="AddSystemMain()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="system_main_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>系統大類名稱</th>
<th>代號</th>
<th>建立時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- Modal 系統大類資料 -->
<div class="modal fade" id="system-main-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
系統大類資料 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form class="system-main-form" id="system-main-form">
<div class="row">
<div class="form-group col-12">
<label class="form-label" for="system_main_name_modal"><span class="text-danger">*</span>大類名稱</label>
<input type="text" id="system_main_name_modal" class="form-control" name="system_main_name_modal">
</div>
<div class="form-group col-12">
<label class="form-label" for="system_main_code_modal"><span class="text-danger">*</span>代號</label>
<input type="text" id="system_main_code_modal" class="form-control" name="system_main_code_modal">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="save-system-main-btn" onclick="SaveSystemMain()">確定</button>
</div>
</div>
</div>
</div>
<!-- /.Modal 系統大類資料 -->

View File

@ -0,0 +1,159 @@
<div class="row mb-5" id="system-main-list">
</div>
<div class="card border mb-g w-100 mb-5" >
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-end">
<div class="text-right ">
<a href="javascript:;" class="btn btn-success waves-effect waves-themed" id="addSystemSub-btn" onclick="AddSystemSub()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<!-- datatable start -->
<table id="system_sub_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>系統大類</th>
<th>系統小類名稱</th>
<th>建立時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="card border mb-g w-100 mb-5" id="submenucard">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap justify-content-end">
<div class="text-right ">
<a href="javascript:;" class="btn btn-success waves-effect waves-themed" id="adddevice_item-btn" onclick="Adddevice_item()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="card-body">
<div class="w-100">
<div class="col-12">
<table id="device_sub_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>序</th>
<th>名稱</th>
<th>點位</th>
<th>單位</th>
<th>是否顯示於平面圖</th>
<th>是否顯示於昇位圖(僅可擇一顯示)</th>
<th>是否加入 - 設備燈號中的點位選單</th>
<th>是否為布林值</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Modal 系統小類資料 -->
<div class="modal fade" id="system-sub-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
系統小類資料 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form class="system-sub-form" id="system-sub-form">
<div class="row">
<div class="form-group col-12">
<label class="form-label" for="system_main_name">大類名稱</label>
<h6 id="system_main_name"></h6>
</div>
<div class="form-group col-12">
<label class="form-label" for="system_sub_name_modal"><span class="text-danger">*</span>小類名稱</label>
<input type="text" id="system_sub_name_modal" class="form-control" name="system_sub_name_modal">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="save-system-sub-btn" onclick="SaveSystemSub()">確定</button>
</div>
</div>
</div>
</div>
<!-- /.Modal 系統小類資料 -->
<div class="modal fade" id="device-sub-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
設備項目 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form class="device-item-sub-form" id="device-item-sub-form">
<div class="row">
<div class="form-group col-12">
<label class="form-label" for="device_sub_name_modal"><span class="text-danger">*</span>名稱</label>
<input type="text" id="device_sub_name_modal" class="form-control" name="device_sub_name_modal">
</div>
<div class="form-group col-12">
<label class="form-label" for="device_sub_points_modal"><span class="text-danger">*</span>點位</label>
<input type="text" id="device_sub_points_modal" class="form-control" name="device_sub_points_modal">
</div>
<div class="form-group col-12">
<label class="form-label" for="device_sub_unit_modal">單位</label>
<input type="text" id="device_sub_unit_modal" class="form-control" name="device_sub_unit_modal">
</div>
<div class="form-group col-12">
<div class="col-12 mb-2 custom-control custom-checkbox align-content-center">
<input type="checkbox" class="custom-control-input" name="is_show" id="is_show" value="1" />
<label class="custom-control-label" for="is_show">是否顯示於平面圖</label>
</div>
</div>
<div class="form-group col-12">
<div class="col-12 mb-2 custom-control custom-checkbox align-content-center">
<input type="checkbox" class="custom-control-input" name="is_show_riserDiagram" id="is_show_riserDiagram" value="1" />
<label class="custom-control-label" for="is_show_riserDiagram">是否顯示於昇位圖</label>
</div>
</div>
<div class="form-group col-12">
<div class="col-12 mb-2 custom-control custom-checkbox align-content-center">
<input type="checkbox" class="custom-control-input" name="is_controll" id="is_controll" value="1" />
<label class="custom-control-label" for="is_controll">是否加入 - 設備燈號中的點位選單</label>
</div>
</div>
<div class="form-group col-12">
<div class="col-12 mb-2 custom-control custom-checkbox align-content-center">
<input type="checkbox" class="custom-control-input" name="is_bool" id="is_bool" value="1" />
<label class="custom-control-label" for="is_bool">是否為布林值</label>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="save-device-item-btn" onclick="Savedevice_item()">確定</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,971 @@

@{
ViewData["MainNum"] = "6";
ViewData["SubNum"] = "1";
ViewData["Title"] = "帳號管理";
}
<ol class="breadcrumb page-breadcrumb">
<li class="breadcrumb-item"><a href="javascript:void(0);">系統管理</a></li>
<li class="breadcrumb-item active">帳號管理</li>
<li class="position-absolute pos-top pos-right d-none d-sm-block"><span class="js-get-date"></span></li>
</ol>
<div class="row">
<div class="col-xl-12">
<div id="panel-5" class="panel">
<div class="panel-container show">
<div class="panel-content">
<ul class="nav nav-tabs" id="tabs" role="tablist">
<li class="nav-item"><a class="nav-link active" data-toggle="tab" href="#tab-user-manager" role="tab"><i class="fal fa-home text-success"></i> <span class="hidden-sm-down ml-1">帳號管理</span></a></li>
<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#tab-role-manager" role="tab"><i class="fal fa-user text-primary"></i> <span class="hidden-sm-down ml-1">角色管理</span></a></li>
<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#tab-role-auth" role="tab"><i class="fal fa-cog text-danger"></i> <span class="hidden-sm-down ml-1">角色權限</span></a></li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane fade show active" id="tab-user-manager" role="tabpanel" aria-labelledby="tab-user-manager">
@Html.Partial("_UserManager")
</div>
<div class="tab-pane fade" id="tab-role-manager" role="tabpanel" aria-labelledby="tab-role-manager">
@Html.Partial("_RoleManager")
</div>
<div class="tab-pane fade" id="tab-role-auth" role="tabpanel" aria-labelledby="tab-role-auth">
@Html.Partial("_RoleAuth")
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
var userManagerTable;
var selected_id = "0";
$(function () {
//#region 切換頁簽判斷被選中的tab
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
selected_tab = $(e.target).attr("href")
switch (selected_tab) {
case "#tab-user-manager":
userManagerTable.ajax.reload();
break;
case "#tab-role-manager":
roleManagerTable.ajax.reload();
break;
case "#tab-role-auth":
var url = "/UserInfo/RoleManagerList";
$.post(url, { post: 1 }, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
if (rel.data.length > 0) {
$('#select_roleId_roleAuth_tab').empty();
$.each(rel.data, function (index, val) {
$("#select_roleId_roleAuth_tab").append($("<option />").val(val.role_guid).text(val.full_name));
});
//預設查詢第一個
$("#select_roleId_roleAuth_tab").val($("#select_roleId_roleAuth_tab option:first").val());
roleAuthTable.ajax.reload();
} else {
$("#select_roleId_roleAuth_tab").empty();
$("#select_roleId_roleAuth_tab").append('<option value="0" disabled>請先新增角色</option>');
$("#select_roleId_roleAuth_tab").val($("#user_role_modal option:first").val());
}
}, 'json');
break;
}
});
//#endregion
//#region 人員基本資料 DataTable
userManagerTable = $("#user_table").DataTable({
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "full_name"
},
{
"data": "account"
},
{
"data": "role_full_name"
},
{
"data": "email"
},
{
"data": "phone"
},
{
"data": "created_at"
},
{
"data": "userinfo_guid",
"render": function (data, type, row, meta) {
if (data == "0") {
return "";
} else {
if (data != '@ViewBag.myUserInfo.Userinfo_guid') {
return '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>';
} else {
return '<button class="btn btn-primary edit-btn">修改</button>';
}
}
}
//"defaultContent": '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>'
}
],
//"order": [[2, "desc"]],
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-guid', data.userinfo_guid);
},
"ajax": {
"url": "/UserInfo/UserManagerList",
"type": "POST",
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
if (@ViewBag.myUserInfo.Layer == 1) {
$.each(this.data, function (index, val) {
if (val.layer == 0) {
val.userinfo_guid = "0"
}
});
}
console.log(this.data);
return data;
}
}
});
//#endregion
});
//#region 新增使用者
function AddUser() {
selected_id = "0";
$("#user-modal .modal-title").html("人員基本資料 - 新增");
$("#user-form").trigger("reset");
$("#user_account_modal").prop("disabled", false);
$(".user_account_same_email_div").show();
$("#user_account_same_email").prop("disabled", false);
$(".user-password-div").show();
GetRoleDropDownList('', 1);
$("#user-modal").modal();
}
//#endregion
//#region 編輯使用者
$('#user_table').on("click", "button.edit-btn", function () {
$("#user-modal .modal-title").html("人員基本資料 - 編輯");
selected_id = $(this).parents('tr').attr('data-guid');
//取得單一使用者管理員
var url = "/UserInfo/GetOneUser/";
var send_data = {
guid: selected_id
}
$.post(url, send_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
else if (rel.code == "9998") {
toast_error(rel.msg);
return;
}
$("#user_name_modal").val(rel.data.full_name);
$("#user_email_modal").val(rel.data.email);
$("#user_account_modal").val(rel.data.account);
$("#user_account_modal").prop("disabled", true);
$(".user_account_same_email_div").hide();
$("#user_account_same_email").prop("disabled", true);
$(".system_admin_password_form_row").hide();
$("#user_phone_modal").val(rel.data.phone);
GetRoleDropDownList(rel.data.role_guid, 1);
$(".user-password-div").hide();
$("#user-modal").modal();
}, 'json');
});
//#endregion
//#region 取得角色下拉選單
function GetRoleDropDownList(selectedVal, type) {
var url = "/UserInfo/RoleManagerList";
$.post(url, { post : 0 }, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
if (type == 1) {
if (rel.data.length > 0) {
$('#user_role_modal').empty();
$.each(rel.data, function (index, val) {
if (@ViewBag.myUserInfo.Layer == 1) {
if (val.layer == 0) {
$("#user_role_modal").append($("<option disabled style='background: #ccc;'/>").val(val.role_guid).text(val.full_name));
} else {
$("#user_role_modal").append($("<option />").val(val.role_guid).text(val.full_name));
}
} else {
$("#user_role_modal").append($("<option />").val(val.role_guid).text(val.full_name));
}
});
if (selectedVal != "") {
$("#user_role_modal").val(selectedVal);
}
else {
//預設查詢第一個
$("#user_role_modal").val($("#user_role_modal option:first").val()).trigger('change');
}
} else {
$("#user_role_modal").empty();
$("#user_role_modal").append('<option value="0" disabled>請先新增角色</option>');
$("#user_role_modal").val($("#user_role_modal option:first").val()).trigger('change');
}
}
else {
if (rel.data.length > 0) {
$('#select_roleId_roleAuth_tab').empty();
$.each(rel.data, function (index, val) {
$("#select_roleId_roleAuth_tab").append($("<option />").val(val.role_guid).text(val.full_name));
});
if (selectedVal != "") {
$("#select_roleId_roleAuth_tab").val(selectedVal);
}
else {
//預設查詢第一個
$("#select_roleId_roleAuth_tab").val($("#select_roleId_roleAuth_tab option:first").val()).trigger('change');
}
} else {
$("#select_roleId_roleAuth_tab").empty();
$("#select_roleId_roleAuth_tab").append('<option value="0" disabled>請先新增角色</option>');
$("#select_roleId_roleAuth_tab").val($("#user_role_modal option:first").val()).trigger('change');
}
}
//toast_ok(rel.msg);
}, 'json');
}
//#endregion
//#region 帳號是否等同Email
$('#user_account_same_email').change(function () {
var email = $("#user_email_modal").val();
if (email == undefined || email == null || email == "") {
toast_warning("請先填寫email");
$(this).prop("checked", false);
return;
}
if (this.checked && selected_id == 0) {
//只提供新增時可透過email填入帳號欄位
$("#user_account_modal").val(email);
$("#user_account_modal").prop("disabled", true);
}
else {
$("#user_account_modal").prop("disabled", false);
}
});
//#endregion
//#region 使用者表單驗證
$("#user-form").validate({
rules: {
user_name_modal: {
required: true,
},
user_email_modal: {
required: true,
email: true,
},
user_account_modal: {
required: true,
}
},
});
//#endregion
//#region 儲存使用者
function SaveUser() {
if ($("#user-form").valid()) {
$("#save-user-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
var url = "/UserInfo/SaveUser";
var send_data = {
Id: selected_id,
Name: $("#user_name_modal").val(),
Email: $("#user_email_modal").val(),
Account: $("#user_account_modal").val(),
Phone: $("#user_phone_modal").val(),
RoleId: $("#user_role_modal").val()
}
$.post(url, send_data, function (rel) {
$("#save-user-btn").html('確定').attr("disabled", false);
if (rel.code != "0000") {
if (rel.code == "9998") {
toast_warning(rel.msg);
return;
}
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
$('#user-modal').modal('hide');
userManagerTable.ajax.reload();
}, 'json')
.fail(function (xhr, status, error) {
$("#save-user-btn").html('確定').attr("disabled", false);
});
}
}
//#endregion
//#region 刪除使用者
$('#user_table').on("click", "button.del-btn", function () {
selected_id = $(this).parents('tr').attr('data-guid');
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/UserInfo/DeleteOneUser";
var send_data = {
guid: selected_id
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
userManagerTable.ajax.reload();
}, 'json');
}
});
});
//#endregion
</script>
<script>
var roleManagerTable;
var selected_roleGUID = "0";
$(function () {
//#region 角色資料 DataTable
roleManagerTable = $("#role_table").DataTable({
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "full_name"
},
{
"data": "created_at"
},
{
"data": "layer",
"render": function (data, type, row, meta) {
if (@ViewBag.myUserInfo.Layer == 0) {
if (data == 1) {
return '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>';
} else {
return '<button class="btn btn-primary edit-btn">修改</button>';
}
} else {
if (data == 1) {
return '<button class="btn btn-primary edit-btn">修改</button> <button class="btn btn-danger del-btn">刪除</button>';
} else {
return '';
}
}
}
}
],
//"order": [[2, "desc"]],
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-guid', data.role_guid);
},
"ajax": {
"url": "/UserInfo/RoleManagerList",
"type": "POST",
"data": function (d) {
d.post = 0;
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
//#endregion
});
//#region 新增角色
function AddRole() {
selected_roleGUID = "0";
$("#role-modal .modal-title").html("角色資料 - 新增");
$("#role-form").trigger("reset");
$("#role-modal").modal();
}
//#endregion
//#region 編輯角色
$('#role_table').on("click", "button.edit-btn", function () {
$("#user-modal .modal-title").html("人員基本資料 - 編輯");
selected_roleGUID = $(this).parents('tr').attr('data-guid');
//取得單一使用者管理員
var url = "/UserInfo/GetOneRole/";
var send_data = {
guid: selected_roleGUID
}
$.post(url, send_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
else if (rel.code == "9998") {
toast_error(rel.msg);
return;
}
$("#role_name_modal").val(rel.data.full_name);
$("#role-modal").modal();
}, 'json');
});
//#endregion
//#region 角色表單驗證
$("#role-form").validate({
rules: {
role_name_modal: {
required: true
}
},
});
//#endregion
//#region 儲存角色
function SaveRole() {
if ($("#role-form").valid()) {
$("#save-role-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
var url = "/UserInfo/SaveRole";
var send_data = {
Id: selected_roleGUID,
Name: $("#role_name_modal").val(),
}
$.post(url, send_data, function (rel) {
$("#save-role-btn").html('確定').attr("disabled", false);
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
$('#role-modal').modal('hide');
roleManagerTable.ajax.reload();
}, 'json')
.fail(function (xhr, status, error) {
$("#save-role-btn").html('確定').attr("disabled", false);
});
}
}
//#endregion
//#region 刪除角色
$('#role_table').on("click", "button.del-btn", function () {
selected_roleGUID = $(this).parents('tr').attr('data-guid');
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
var url = "/UserInfo/DeleteOneRole";
var send_data = {
guid: selected_roleGUID
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
}
else if (rel.code == "9997") {
var htnl = rel.msg + "<br>"
Swal.fire(
{
title: "刪除失敗",
icon: 'warning',
html: htnl,
});
}
else {
toast_warning(rel.msg);
}
return;
}
else {
toast_ok(rel.msg);
roleManagerTable.ajax.reload();
return;
}
}, 'json');
}
});
});
//#endregion
</script>
<script>
var roleAuthTable;
var roleAuthNotJoinTable;
var selected_roleAuthGUID = "0";
var selected_build = "0";
var saveCheckAuth = [];
//var CheckCount = 0;
var AllCount = 0;
//var frontEndCheckAuth = [];
//var backEndCheckAuth = [];
//var oddAuthType;
//var oddBuild;
$(function () {
var url = "/UserInfo/RoleManagerList";
$.post(url, { post: 1 }, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
if (rel.data.length > 0) {
$('#select_roleId_roleAuth_tab').empty();
$.each(rel.data, function (index, val) {
$("#select_roleId_roleAuth_tab").append($("<option />").val(val.role_guid).text(val.full_name));
});
//預設查詢第一個
$("#select_roleId_roleAuth_tab").val($("#select_roleId_roleAuth_tab option:first").val());
//#region 角色資料 DataTable
roleAuthTable = $("#roleAuth_table").DataTable({
"columns": [
{
"data": null,
"render": function (data, type, row, meta) {
return meta.row + 1;
}
},
{
"data": "role_full_name"
},
{
"data": "authTypeText"
},
{
"data": "building_full_name"
},
{
"data": "mainName"
},
{
"data": "subName"
},
{
"data": "created_at"
},
{
"data": null,
"defaultContent": '<button class="btn btn-danger del-btn">刪除</button>'
}
],
//"order": [[2, "desc"]],
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-guid', data.role_guid);
$(row).attr('data-authCode', data.authCode);
},
"ajax": {
"url": "/UserInfo/RoleAuthList",
"type": "POST",
"data": function (d) {
d.SelectedRoleId = $('#select_roleId_roleAuth_tab').val();
},
"dataSrc": function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
data = rel.data;
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
}
});
//#endregion
} else {
$("#select_roleId_roleAuth_tab").empty();
$("#select_roleId_roleAuth_tab").append('<option value="0" disabled>請先新增角色</option>');
$("#select_roleId_roleAuth_tab").val($("#user_role_modal option:first").val());
}
}, 'json');
//#region 角色未加入權限列表 DataTable
roleAuthNotJoinTable = $("#roleAuth_NotJoin_table").DataTable({
//"order": [[1, "desc"]],
"columns": [
{
"data": "authCode"
},
{
"data": "mainName"
},
{
"data": "subName"
}
],
"columnDefs": [{
'targets': 0,
'searchable': false,
'orderable': false,
'className': 'dt-body-center',
'render': function (data, type, full, meta) {
var check_html = "";
check_html += '<div class="custom-control custom-checkbox">';
//判斷是否要Check
var checkHtml = "";
if (saveCheckAuth.length > 0) {
var filterAuth = saveCheckAuth.filter(function (i, n) {
return i === data;
});
if (filterAuth.length > 0) {
checkHtml = "checked";
}
}
check_html += `<input type="checkbox" class="custom-control-input" name="selectedAuthPage[]" id="auth-page-${data}" value="${data}" ${checkHtml} /> `;
check_html += '<label class="custom-control-label" for="auth-page-' + data + '" />';
check_html += '</div>';
return check_html;
}
}],
'createdRow': function (row, data, dataIndex) {
$(row).attr('data-authCode', data.authCode);
},
"ajax": {
"url": "/UserInfo/GetRoleNotAuthPageList",
"type": "POST",
"data": function (d) {
d.SelectedRoleId = $('#select_roleId_roleAuth_tab').val();
d.SelectedAuthType = $("#select_authType").val();
d.SelectedBuild = selected_build;
},
"dataSrc": function (rel) {
if (rel.data.code == "9999") {
toast_error(rel.data.msg);
return;
}
data = rel.data;
AllCount = data.length;
console.log("AllCount", AllCount);
if (data == null || data.length == 0) {
this.data = [];
}
return data;
}
},
//"drawCallback": function (settings) {
// if (AllCount > 0) {
// var rows = roleAuthNotJoinTable.rows({ 'search': 'applied' }).nodes().length;
// var checkAuths = $("input[name='selectedAuthPage[]']:checked", rows).map(function () {
// return $(this).val();
// }).get();
// console.log("drawCallback", checkAuths.length);
// if (AllCount == CheckCount.length) {
// $("#select-all-role-auth").prop('checked', true);
// }
// else {
// $("#select-all-role-auth").prop('checked', false);
// }
// }
// else {
// $("#select-all-role-auth").prop('checked', false);
// }
// CheckCount = 0;
//}
});
//#endregion
});
//#region 角色權限全選
$("#select-all-role-auth").change(function () {
var rows = roleAuthNotJoinTable.rows({ 'search': 'applied' }).nodes();
$("input[name='selectedAuthPage[]']", rows).prop('checked', this.checked);
});
//#endregion
//#region 選擇角色下拉式選單select_option
$("#select_roleId_roleAuth_tab").change(function () {
roleAuthTable.ajax.reload();
});
//#endregion
//#region 新增角色權限
async function AddRoleAuth() {
$("#select_authType").val(1);
await authTypeChange();
//oddBuild = $("#select_building").val();
roleAuthNotJoinTable.ajax.reload();
saveCheckAuth = [];
$("#role-auth-modal").modal();
}
//#endregion
//#region 選擇角色類型下拉式選單select_option
function authTypeChange() {
return new Promise((resolve, reject) => {
if ($("#select_authType").val() == "1") {
$("#select_building").show();
var url = "/BuildInfo/BuildInfoList";
$.post(url, null, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
if (rel.data.length > 0) {
$('#select_building').empty();
$.each(rel.data, function (index, val) {
$("#select_building").append($("<option />").val(val.building_guid).text(val.full_name));
});
//預設查詢第一個
$("#select_building").val($("#select_building option:first").val());
selected_build = $("#select_building option:first").val();
roleAuthNotJoinTable.ajax.reload();
//#endregion
} else {
$("#select_building").empty();
$("#select_building").append('<option value="0" disabled>請先新增區域</option>');
$("#select_building").val($("#select_building option:first").val());
}
resolve();
}, 'json');
}
else {
selected_build = "0";
$("#select_building").hide();
roleAuthNotJoinTable.ajax.reload();
resolve();
}
});
}
$("#select_authType").change(function () {
$("#select-all-role-auth").prop('checked', false);
CheckAuthMain();
authTypeChange();
});
//#endregion
//#region 選擇區域下拉式選單select_option
$("#select_building").change(function () {
$("#select-all-role-auth").prop('checked', false);
CheckAuthMain();
selected_build = $("#select_building").val();
roleAuthNotJoinTable.ajax.reload();
});
//#endregion
//#region 儲存Check
async function CheckAuthMain() {
await CheckAuth();
}
function CheckAuth() {
return new Promise((resolve, reject) => {
var rows = roleAuthNotJoinTable.rows({ 'search': 'applied' }).nodes();
//取得被選擇的角色權限
var checkAuths = $("input[name='selectedAuthPage[]']:checked", rows).map(function () {
return $(this).val();
}).get();
var uncheckAuths = $("input[name='selectedAuthPage[]']:not(:checked)", rows).map(function () {
return $(this).val();
}).get();
//勾選
if (checkAuths.length > 0) {
$.each(checkAuths, function (index, val) {
var dbindex = saveCheckAuth.findIndex(x => x == val);
if (dbindex == -1) {
saveCheckAuth.push(val);
}
});
}
//未勾選
if (uncheckAuths.length > 0) {
$.each(uncheckAuths, function (index, val) {
var dbindex = saveCheckAuth.findIndex(x => x == val);
if (dbindex >= 0) {
saveCheckAuth.splice(dbindex, 1);
}
});
}
resolve();
});
}
//#endregion
//#region 刪除角色權限
$('#roleAuth_table').on("click", "button.del-btn", function () {
var row_guid = $(this).parents('tr').attr('data-guid');
var row_authCode = $(this).parents('tr').attr('data-authCode');
//var split_arr = row_id_authCode.split("_");
Swal.fire(
{
title: "刪除",
text: "你確定是否刪除此筆資料?",
type: "warning",
icon: 'warning',
showCancelButton: true,
confirmButtonText: "是",
cancelButtonText: "否"
}).then(function (result) {
if (result.value) {
//取得單一系統管理員
var url = "/UserInfo/DeleteOneRoleAuth/";
var send_data = {
RoleId: row_guid,
AuthCode: row_authCode
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
roleAuthTable.ajax.reload();
}, 'json');
}
});
});
//#endregion
//#region 儲存角色權限
function SaveRoleAuth() {
CheckAuthMain();
$("#save-role-auth-btn").html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>').attr("disabled", true);
var url = "/UserInfo/SaveRoleAuth";
var send_data = {
SelectedRoleId: $('#select_roleId_roleAuth_tab').val(),
SaveCheckAuth: saveCheckAuth
}
$.post(url, send_data, function (rel) {
$("#save-role-auth-btn").html('確定').attr("disabled", false);
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
toast_ok(rel.msg);
$("#role-auth-modal").modal('hide');
roleAuthTable.ajax.reload();
}, 'json')
.fail(function (xhr, status, error) {
$("#save-role-auth-btn").html('確定').attr("disabled", false);
});
}
//#endregion
</script>
}

View File

@ -0,0 +1,96 @@
<div class="row mb-5">
<div class="panel-toolbar ml-2">
<div class="d-flex position-relative ml-auto" style="max-width: 8rem;">
<div class="form-group">
<select class="form-control" id="select_roleId_roleAuth_tab">
@*<option value="0" disabled>請先新增角色</option>*@
</select>
</div>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-12">
<a href="javascript:;" class="btn btn-success waves-effect waves-themed mb-3" onclick="AddRoleAuth()"><span class="fal fa-plus mr-1"></span> 加入可用功能</a>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="roleAuth_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>#</th>
<th>角色</th>
<th>功能類型</th>
<th>區域</th>
<th>功能名稱</th>
<th>功能細項名稱</th>
<th>建立時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- Modal 角色權限 -->
<div class="modal fade" id="role-auth-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
角色權限 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<div class="row mb-5">
<div class="panel-toolbar ml-2">
<div class="d-flex position-relative ml-auto" style="max-width: 8rem;">
<div class="form-group">
<select class="form-control" id="select_authType" onchange="authTypeChange()">
<option value="1">前台</option>
<option value="2">後台</option>
</select>
</div>
</div>
</div>
<div class="panel-toolbar ml-2">
<div class="d-flex position-relative ml-auto" style="max-width: 8rem;">
<div class="form-group">
<select class="form-control" id="select_building">
</select>
</div>
</div>
</div>
</div>
<table id="roleAuth_NotJoin_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="select-all-role-auth">
<label class="custom-control-label" for="select-all-role-auth">全選</label>
</div>
</th>
<th>功能大項</th>
<th>功能名稱</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="save-role-auth-btn" onclick="SaveRoleAuth()">確定</button>
</div>
</div>
</div>
</div>
<!-- /.角色權限 -->

View File

@ -0,0 +1,53 @@
<div class="row mb-3">
<div class="col-12">
<a href="javascript:;" class="btn btn-success waves-effect waves-themed mb-3" onclick="AddRole()"><span class="fal fa-plus mr-1"></span> 新增</a>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="role_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>#</th>
<th>名稱</th>
<th>建立時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- Modal 角色資料 -->
<div class="modal fade" id="role-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-md" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
角色資料 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form class="role-form" id="role-form">
<div class="row">
<div class="form-group col-lg-12">
<label class="form-label" for="user_name_modal"><span class="text-danger">*</span>名稱</label>
<input type="text" id="role_name_modal" name="role_name_modal" class="form-control">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="save-role-btn" onclick="SaveRole()">確定</button>
</div>
</div>
</div>
</div>
<!-- /.Modal 人員基本資料 -->

View File

@ -0,0 +1,89 @@
<div class="row mb-3">
<div class="col-12">
<a href="javascript:void(0);" class="btn btn-success waves-effect waves-themed mb-3" id="addUser-btn" onclick="AddUser()"><span class="fal fa-plus mr-1"></span>新增</a>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- datatable start -->
<table id="user_table" class="table table-bordered table-hover m-0 text-center">
<thead class="thead-themed">
<tr>
<th>#</th>
<th>姓名</th>
<th>帳號</th>
<th>角色</th>
<th>email</th>
<th>手機號碼</th>
<th>建立時間</th>
<th>功能</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- Modal 人員基本資料 -->
<div class="modal fade" id="user-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
人員基本資料 - 新增
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<form class="user-form" id="user-form">
<div class="row">
<div class="form-group col-lg-6">
<label class="form-label" for="user_name_modal"><span class="text-danger">*</span>姓名</label>
<input type="text" id="user_name_modal" name="user_name_modal" class="form-control">
</div>
<div class="form-group col-lg-6">
<label class="form-label" for="user_email_modal"><span class="text-danger">*</span>email</label>
<input type="text" id="user_email_modal" name="user_email_modal" class="form-control">
</div>
<div class="form-group col-lg-6">
<div style="margin-bottom: 0.3rem">
<label class="form-label" for="user_account_modal"><span class="text-danger">*</span>帳號</label>
<input type="text" id="user_account_modal" name="user_account_modal" class="form-control">
</div>
<div class="custom-control custom-checkbox user_account_same_email_div">
<input type="checkbox" class="custom-control-input" id="user_account_same_email" />
<label class="custom-control-label" for="user_account_same_email">與email相同</label>
</div>
</div>
<div class="form-group col-lg-6 user-password-div">
<label class="form-label" for="user_password_modal">密碼</label>
<input type="password" id="user_password_modal" name="user_password_modal" class="form-control" placeholder="由系統產生" disabled>
</div>
<div class="form-group col-lg-6">
<label class="form-label" for="user_role_modal">角色權限</label>
<select class="form-control" id="user_role_modal">
</select>
</div>
<div class="form-group col-lg-6">
<label class="form-label" for="user_phone_modal">手機號碼</label>
<input type="text" id="user_phone_modal" class="form-control" maxlength="10" onkeyup="if(event.keyCode !=37 && event.keyCode != 39)value=value.replace(/\D/g,'')" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="save-user-btn" onclick="SaveUser()">確定</button>
</div>
</div>
</div>
</div>
<!-- /.Modal 人員基本資料 -->

Some files were not shown because too many files have changed in this diff Show More