加入專案檔案。
This commit is contained in:
parent
8dd1f67562
commit
dec698413b
20
AlarmMonitorWorkerService/AlarmMonitorWorkerService.csproj
Normal file
20
AlarmMonitorWorkerService/AlarmMonitorWorkerService.csproj
Normal 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>
|
25
AlarmMonitorWorkerService/Models/EmergencyDevice.cs
Normal file
25
AlarmMonitorWorkerService/Models/EmergencyDevice.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
19
AlarmMonitorWorkerService/Models/Variable.cs
Normal file
19
AlarmMonitorWorkerService/Models/Variable.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
67
AlarmMonitorWorkerService/Program.cs
Normal file
67
AlarmMonitorWorkerService/Program.cs
Normal 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");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
10
AlarmMonitorWorkerService/Properties/launchSettings.json
Normal file
10
AlarmMonitorWorkerService/Properties/launchSettings.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"AlarmMonitorWorkerService": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"environmentVariables": {
|
||||||
|
"DOTNET_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
AlarmMonitorWorkerService/Quartz/JobSchedule.cs
Normal file
45
AlarmMonitorWorkerService/Quartz/JobSchedule.cs
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
211
AlarmMonitorWorkerService/Quartz/Jobs/AlarmMonitorJob.cs
Normal file
211
AlarmMonitorWorkerService/Quartz/Jobs/AlarmMonitorJob.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
71
AlarmMonitorWorkerService/Quartz/QuartzHostedService.cs
Normal file
71
AlarmMonitorWorkerService/Quartz/QuartzHostedService.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
AlarmMonitorWorkerService/Quartz/SingletonJobFactory.cs
Normal file
26
AlarmMonitorWorkerService/Quartz/SingletonJobFactory.cs
Normal 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
AlarmMonitorWorkerService/Worker.cs
Normal file
29
AlarmMonitorWorkerService/Worker.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
AlarmMonitorWorkerService/appsettings.Development.json
Normal file
28
AlarmMonitorWorkerService/appsettings.Development.json
Normal 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=="
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
28
AlarmMonitorWorkerService/appsettings.json
Normal file
28
AlarmMonitorWorkerService/appsettings.json
Normal 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=="
|
||||||
|
//},
|
||||||
|
}
|
||||||
|
}
|
12
Backend/.config/dotnet-tools.json
Normal file
12
Backend/.config/dotnet-tools.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"dotnet-ef": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"commands": [
|
||||||
|
"dotnet-ef"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
128
Backend/ApiControllers/DeviceApiController.cs
Normal file
128
Backend/ApiControllers/DeviceApiController.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
81
Backend/ApiControllers/MyBaseApiController.cs
Normal file
81
Backend/ApiControllers/MyBaseApiController.cs
Normal 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
45
Backend/Backend.csproj
Normal 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>
|
588
Backend/Controllers/BuildInfoController.cs
Normal file
588
Backend/Controllers/BuildInfoController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
557
Backend/Controllers/BuildMenuController.cs
Normal file
557
Backend/Controllers/BuildMenuController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
751
Backend/Controllers/DeviceImportController.cs
Normal file
751
Backend/Controllers/DeviceImportController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
1618
Backend/Controllers/DeviceManageController.cs
Normal file
1618
Backend/Controllers/DeviceManageController.cs
Normal file
File diff suppressed because it is too large
Load Diff
232
Backend/Controllers/EmergencyContactController.cs
Normal file
232
Backend/Controllers/EmergencyContactController.cs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
Backend/Controllers/EmergencyDeviceMenuController.cs
Normal file
50
Backend/Controllers/EmergencyDeviceMenuController.cs
Normal 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;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
278
Backend/Controllers/EmergencyGroupingController.cs
Normal file
278
Backend/Controllers/EmergencyGroupingController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
94
Backend/Controllers/EmergencyRecordController.cs
Normal file
94
Backend/Controllers/EmergencyRecordController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
558
Backend/Controllers/EmergencySettingController.cs
Normal file
558
Backend/Controllers/EmergencySettingController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
Backend/Controllers/HomeController.cs
Normal file
37
Backend/Controllers/HomeController.cs
Normal 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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
151
Backend/Controllers/LoginController.cs
Normal file
151
Backend/Controllers/LoginController.cs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
101
Backend/Controllers/MybaseController.cs
Normal file
101
Backend/Controllers/MybaseController.cs
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
7
Backend/Controllers/NpoiMemoryStream.cs
Normal file
7
Backend/Controllers/NpoiMemoryStream.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Backend.Controllers
|
||||||
|
{
|
||||||
|
internal class NpoiMemoryStream
|
||||||
|
{
|
||||||
|
public bool AllowClose { get; set; }
|
||||||
|
}
|
||||||
|
}
|
366
Backend/Controllers/RescueDeviceController.cs
Normal file
366
Backend/Controllers/RescueDeviceController.cs
Normal 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");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
173
Backend/Controllers/ServicePlanController.cs
Normal file
173
Backend/Controllers/ServicePlanController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
804
Backend/Controllers/SystemCategoryController.cs
Normal file
804
Backend/Controllers/SystemCategoryController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
640
Backend/Controllers/UserInfoController.cs
Normal file
640
Backend/Controllers/UserInfoController.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
226
Backend/Controllers/VariableController.cs
Normal file
226
Backend/Controllers/VariableController.cs
Normal 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
90
Backend/Jwt/JwtHelpers.cs
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
19
Backend/Jwt/JwtSettings.cs
Normal file
19
Backend/Jwt/JwtSettings.cs
Normal 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
23
Backend/Jwt/TnToken.cs
Normal 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
22
Backend/Models/Archive.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
34
Backend/Models/BackgroundServiceMessageNotificationTask.cs
Normal file
34
Backend/Models/BackgroundServiceMessageNotificationTask.cs
Normal 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; } }
|
||||||
|
}
|
||||||
|
}
|
44
Backend/Models/BackgroundServicePlan.cs
Normal file
44
Backend/Models/BackgroundServicePlan.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
Backend/Models/BackgroundServiceTask.cs
Normal file
40
Backend/Models/BackgroundServiceTask.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
73
Backend/Models/BuildMenu.cs
Normal file
73
Backend/Models/BuildMenu.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
Backend/Models/BuildModel.cs
Normal file
57
Backend/Models/BuildModel.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
70
Backend/Models/BuildingCollapse.cs
Normal file
70
Backend/Models/BuildingCollapse.cs
Normal 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
266
Backend/Models/Device.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
88
Backend/Models/DeviceImport.cs
Normal file
88
Backend/Models/DeviceImport.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
30
Backend/Models/EmergencyContact.cs
Normal file
30
Backend/Models/EmergencyContact.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
43
Backend/Models/EmergencyGrouping.cs
Normal file
43
Backend/Models/EmergencyGrouping.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
45
Backend/Models/EmergencyRecord.cs
Normal file
45
Backend/Models/EmergencyRecord.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
63
Backend/Models/EmergencySetting.cs
Normal file
63
Backend/Models/EmergencySetting.cs
Normal 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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Backend/Models/ErrorViewModel.cs
Normal file
11
Backend/Models/ErrorViewModel.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Backend.Models
|
||||||
|
{
|
||||||
|
public class ErrorViewModel
|
||||||
|
{
|
||||||
|
public string RequestId { get; set; }
|
||||||
|
|
||||||
|
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
|
}
|
||||||
|
}
|
15
Backend/Models/ForgotPasswordViewModel.cs
Normal file
15
Backend/Models/ForgotPasswordViewModel.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
19
Backend/Models/LoginViewModel.cs
Normal file
19
Backend/Models/LoginViewModel.cs
Normal 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
87
Backend/Models/Mybase.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
14
Backend/Models/ObixApiConfig.cs
Normal file
14
Backend/Models/ObixApiConfig.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
17
Backend/Models/OperatorLog.cs
Normal file
17
Backend/Models/OperatorLog.cs
Normal 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
63
Backend/Models/Parking.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
67
Backend/Models/RescueDevice.cs
Normal file
67
Backend/Models/RescueDevice.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
Backend/Models/SMSConfig.cs
Normal file
15
Backend/Models/SMSConfig.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
16
Backend/Models/SMTPConfig.cs
Normal file
16
Backend/Models/SMTPConfig.cs
Normal 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
243
Backend/Models/Share.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
75
Backend/Models/SystemCategory.cs
Normal file
75
Backend/Models/SystemCategory.cs
Normal 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
166
Backend/Models/UserInfo.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
274
Backend/Models/WeatherAPIJob.cs
Normal file
274
Backend/Models/WeatherAPIJob.cs
Normal 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
26
Backend/Program.cs
Normal 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>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
29
Backend/Properties/launchSettings.json
Normal file
29
Backend/Properties/launchSettings.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
179
Backend/Services/Implement/BackgroundService.cs
Normal file
179
Backend/Services/Implement/BackgroundService.cs
Normal 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
181
Backend/Startup.cs
Normal 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?}");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
609
Backend/Views/BuildInfo/Index.cshtml
Normal file
609
Backend/Views/BuildInfo/Index.cshtml
Normal 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>
|
||||||
|
}
|
69
Backend/Views/BuildInfo/_BuildFloor.cshtml
Normal file
69
Backend/Views/BuildInfo/_BuildFloor.cshtml
Normal 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 樓層設定 -->
|
65
Backend/Views/BuildInfo/_BuildInfo.cshtml
Normal file
65
Backend/Views/BuildInfo/_BuildInfo.cshtml
Normal 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 區域基本資料 -->
|
992
Backend/Views/BuildMenu/Index.cshtml
Normal file
992
Backend/Views/BuildMenu/Index.cshtml
Normal 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>
|
||||||
|
}
|
537
Backend/Views/DeviceImport/Index.cshtml
Normal file
537
Backend/Views/DeviceImport/Index.cshtml
Normal 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>
|
||||||
|
}
|
64
Backend/Views/DeviceImport/_RawDataCheck.cshtml
Normal file
64
Backend/Views/DeviceImport/_RawDataCheck.cshtml
Normal 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>
|
26
Backend/Views/DeviceImport/_RawDataImport.cshtml
Normal file
26
Backend/Views/DeviceImport/_RawDataImport.cshtml
Normal 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>
|
3120
Backend/Views/DeviceManage/Index.cshtml
Normal file
3120
Backend/Views/DeviceManage/Index.cshtml
Normal file
File diff suppressed because it is too large
Load Diff
279
Backend/Views/EmergencyContact/Index.cshtml
Normal file
279
Backend/Views/EmergencyContact/Index.cshtml
Normal 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>
|
||||||
|
}
|
86
Backend/Views/EmergencyDeviceMenu/Index.cshtml
Normal file
86
Backend/Views/EmergencyDeviceMenu/Index.cshtml
Normal 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>
|
||||||
|
}
|
1
Backend/Views/EmergencyDeviceMenu/_AlarmDevice.cshtml
Normal file
1
Backend/Views/EmergencyDeviceMenu/_AlarmDevice.cshtml
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
195
Backend/Views/EmergencyDeviceMenu/_EmergencyDevice.cshtml
Normal file
195
Backend/Views/EmergencyDeviceMenu/_EmergencyDevice.cshtml
Normal 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>
|
568
Backend/Views/EmergencyGrouping/Index.cshtml
Normal file
568
Backend/Views/EmergencyGrouping/Index.cshtml
Normal 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>
|
||||||
|
|
||||||
|
}
|
416
Backend/Views/EmergencyRecord/Index.cshtml
Normal file
416
Backend/Views/EmergencyRecord/Index.cshtml
Normal 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>
|
||||||
|
}
|
1505
Backend/Views/EmergencySetting/Index.cshtml
Normal file
1505
Backend/Views/EmergencySetting/Index.cshtml
Normal file
File diff suppressed because it is too large
Load Diff
7
Backend/Views/Home/Index.cshtml
Normal file
7
Backend/Views/Home/Index.cshtml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Home Page";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">Welcome</h1>
|
||||||
|
</div>
|
6
Backend/Views/Home/Privacy.cshtml
Normal file
6
Backend/Views/Home/Privacy.cshtml
Normal 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>
|
81
Backend/Views/Login/ForgotPassword.cshtml
Normal file
81
Backend/Views/Login/ForgotPassword.cshtml
Normal 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>
|
132
Backend/Views/Login/Index.cshtml
Normal file
132
Backend/Views/Login/Index.cshtml
Normal 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>
|
||||||
|
|
||||||
|
|
398
Backend/Views/RescueDevice/AED.cshtml
Normal file
398
Backend/Views/RescueDevice/AED.cshtml
Normal 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>
|
||||||
|
}
|
417
Backend/Views/RescueDevice/FireExtinguisher.cshtml
Normal file
417
Backend/Views/RescueDevice/FireExtinguisher.cshtml
Normal 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>
|
||||||
|
}
|
339
Backend/Views/ServicePlan/Index.cshtml
Normal file
339
Backend/Views/ServicePlan/Index.cshtml
Normal 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>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
25
Backend/Views/Shared/Error.cshtml
Normal file
25
Backend/Views/Shared/Error.cshtml
Normal 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>
|
992
Backend/Views/Shared/_Layout.cshtml
Normal file
992
Backend/Views/Shared/_Layout.cshtml
Normal 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">@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 <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">×</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">×</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>
|
2
Backend/Views/Shared/_ValidationScriptsPartial.cshtml
Normal file
2
Backend/Views/Shared/_ValidationScriptsPartial.cshtml
Normal 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>
|
790
Backend/Views/SystemCategory/Index.cshtml
Normal file
790
Backend/Views/SystemCategory/Index.cshtml
Normal 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>
|
||||||
|
}
|
58
Backend/Views/SystemCategory/_SystemMain.cshtml
Normal file
58
Backend/Views/SystemCategory/_SystemMain.cshtml
Normal 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 系統大類資料 -->
|
159
Backend/Views/SystemCategory/_SystemSub.cshtml
Normal file
159
Backend/Views/SystemCategory/_SystemSub.cshtml
Normal 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>
|
971
Backend/Views/UserInfo/Index.cshtml
Normal file
971
Backend/Views/UserInfo/Index.cshtml
Normal 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>
|
||||||
|
}
|
96
Backend/Views/UserInfo/_RoleAuth.cshtml
Normal file
96
Backend/Views/UserInfo/_RoleAuth.cshtml
Normal 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>
|
||||||
|
<!-- /.角色權限 -->
|
53
Backend/Views/UserInfo/_RoleManager.cshtml
Normal file
53
Backend/Views/UserInfo/_RoleManager.cshtml
Normal 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 人員基本資料 -->
|
89
Backend/Views/UserInfo/_UserManager.cshtml
Normal file
89
Backend/Views/UserInfo/_UserManager.cshtml
Normal 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
Loading…
Reference in New Issue
Block a user