Update MD2

This commit is contained in:
Chris Chen
2024-05-02 15:24:13 -07:00
parent eea11029e9
commit ed89de631b
93 changed files with 3392 additions and 152 deletions
@@ -0,0 +1,148 @@
using Church.Net.Entity;
using Church.Net.Entity.Interface;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Authorize]
public class ApiControllerBase<T> : ControllerBase where T : IEntity
{
protected readonly ICrudLogic<T> logic;
public ApiControllerBase(ICrudLogic<T> logic)
{
this.logic = logic;
}
[HttpGet]
public virtual async Task<IEnumerable<T>> GetAll()
{
return await Task.Run(() => { return logic.GetAll(); });
}
[HttpGet]
public virtual async Task<T> GetById(string id)
{
return await Task.Run(() => {
return logic.GetById(id);
});
}
[HttpPost]
public virtual async Task<int> Update(T entity)
{
return await Task.Run(() => {
return logic.Update(entity);
});
}
[HttpPost]
public virtual async Task<T> CreateOrUpdate([FromBody] T entity)
{
return await Task.Run(() =>
{
logic.CreateOrUpdate(entity, out string id);
return entity;
});
}
[HttpPost]
public virtual async Task<IEnumerable<T>> CreateOrUpdateAll([FromBody] IEnumerable<T> entitys)
{
return await Task.Run(() =>
{
foreach (var item in entitys)
{
logic.CreateOrUpdate(item, out string id);
}
return entitys;
});
}
[HttpDelete("{id}")]
public virtual async Task<T> Delete(string id)
{
return await Task.Run(() => {
var entity = logic.GetById(id);
if (entity != null)
{
logic.Delete(entity);
}
return entity;
});
}
}
[Authorize]
public class CombinedKeyApiControllerBase<T> : ControllerBase where T : ICombinedKeyEntity
{
protected readonly ICombinedKeyCrudLogic<T> logic;
public CombinedKeyApiControllerBase(ICombinedKeyCrudLogic<T> logic)
{
this.logic = logic;
}
[HttpGet]
public virtual async Task<IEnumerable<T>> GetAll()
{
return await Task.Run(() => { return logic.GetAll(); });
}
[HttpGet]
public virtual async Task<T> GetById(string[] ids)
{
return await Task.Run(() => {
return logic.GetById(ids);
});
}
[HttpPost]
public virtual async Task<int> Update(T entity)
{
return await Task.Run(() => {
return logic.Update(entity);
});
}
[HttpPost]
public virtual async Task<T> CreateOrUpdate([FromBody] T entity)
{
return await Task.Run(() =>
{
logic.CreateOrUpdate(entity);
return entity;
});
}
[HttpPost]
public virtual async Task<IEnumerable<T>> CreateOrUpdateAll([FromBody] IEnumerable<T> entitys)
{
return await Task.Run(() =>
{
foreach (var item in entitys)
{
logic.CreateOrUpdate(item);
}
return entitys;
});
}
[HttpDelete]
public virtual async Task<T> Delete(string[] ids)
{
return await Task.Run(() => {
var entity = logic.GetById(ids);
if (entity != null)
{
logic.Delete(entity);
}
return entity;
});
}
}
}
@@ -0,0 +1,135 @@
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Church.Net.Entity;
using Church.Net.Utility;
using Microsoft.AspNetCore.Mvc;
using QRCoder;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Processing;
using WebAPI.Logics;
using WebAPI.Logics.Interface;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class BestController : ApiControllerBase<HappinessBEST>
{
private readonly ICrudLogic<HappinessBEST> logic;
private readonly ICrudLogic<HappinessWeek> weekLogic;
private readonly PastoralDomainLogic cellGroupLogic;
public BestController(
ICrudLogic<HappinessBEST> logic,
ICrudLogic<HappinessWeek> weekLogic,
PastoralDomainLogic cellGroupLogic
) : base(logic)
{
this.logic = logic;
this.weekLogic = weekLogic;
this.cellGroupLogic = cellGroupLogic;
}
// GET api/<BestController>/5
public override Task<IEnumerable<HappinessBEST>> GetAll()
{
return base.GetAll();
}
public override Task<HappinessBEST> GetById(string id)
{
return Task<HappinessBEST>.Run(() => {
var best = logic.GetById(id);
best.HappinessGroup = cellGroupLogic.GetById(best.GroupId);
best.HappinessGroup.HappinessWeeks = weekLogic.GetAll(w => w.GroupId == best.GroupId).OrderBy(w=>w.SEQ).ToList();
return best;
});
}
[HttpGet()]
public async Task<IActionResult> GetInvitationQRcode(string id)
{
QRCodeGenerator gen = new QRCodeGenerator();
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode($"https://happiness.tours/invitation/{id}", QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
var qrCodeImage = qrCode.GetGraphic(3);
string qrCodeImagePath = "/App_Data/ScaneMeQrCode.png";
var backgroundBitmap = SixLabors.ImageSharp.Image.Load(qrCodeImagePath);
//string qrCodeImagePath = Environment.GetEnvironmentVariable("AppData");
//HttpContext.Current.Server.MapPath("~/App_Data/");
//var fullPath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data/ScaneMeQrCode.png");
//System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data/yourXmlFile.xml");
int positionLeft = 0;
int positionTop = 0;
var best = logic.GetById(id);
if (best != null)
{
using (var memoryStream = new MemoryStream())
{
//fileStream.CopyTo(memoryStream);
var image = Superimpose(best.Name, backgroundBitmap, qrCodeImage, 10, 32);
image.Scalling(75);
image.SaveAsPng(memoryStream);
byte[] byteImage = memoryStream.ToArray();
return File(byteImage, "image/png");
}
}
return this.NotFound();
}
[HttpPost]
public int UpdateBestWeek(HappinessWeek week)
{
return cellGroupLogic.UpdateWeekInfo(week);
}
private Font arialFont;
[NonAction]
public Image Superimpose(string bestName, Image largeBmp, Image smallBmp, int? x = null, int? y = null)
{
FontCollection collection = new();
FontFamily family = collection.Add("/App_Data/arial.ttf");
arialFont = family.CreateFont(12, FontStyle.Italic);
//Graphics g = Graphics.FromImage(largeBmp);
//g.CompositingMode = CompositingMode.SourceOver;
//smallBmp.MakeTransparent();
int margin = 5;
if (!x.HasValue)
{
x = largeBmp.Width - smallBmp.Width - margin;
}
if (!y.HasValue)
{
y = largeBmp.Height - smallBmp.Height - margin;
}
var scale = 0.8;
var scaleWidth = (int)(smallBmp.Width * scale);
var scaleHeight = (int)(smallBmp.Height * scale);
largeBmp.Mutate(x => x.DrawText(bestName, arialFont, Color.Black, new PointF(10, 10)));
smallBmp.Scalling(80);
largeBmp.Mutate(ctx => ctx.DrawImage(smallBmp, new Point(x.Value, y.Value),1f));
return largeBmp;
}
}
}
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Church.Net.DAL.EF;
using Church.Net.Entity;
using WebAPI.Logics;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class CellGroupRoutineEventAttendeesController : CombinedKeyApiControllerBase<CellGroupRoutineEventAttendee>
{
public CellGroupRoutineEventAttendeesController(ICombinedKeyCrudLogic<CellGroupRoutineEventAttendee> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Church.Net.DAL.EF;
using Church.Net.Entity;
using Church.Net.Utility;
using Church.Net.DAL.EFCoreDBF;
using WebAPI.Logics;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class CellGroupRoutineEventsController : ApiControllerBase<CellGroupRoutineEvent>
{
private readonly PastoralDomainLogic logic;
private readonly ICombinedKeyCrudLogic<CellGroupRoutineEventPrayer> prayerLogic;
private readonly ICombinedKeyCrudLogic<CellGroupRoutineEventAttendee> dinnerLogic;
public CellGroupRoutineEventsController(
PastoralDomainLogic logic,
ICrudLogic<CellGroupRoutineEvent> crudLogic,
ICombinedKeyCrudLogic<CellGroupRoutineEventPrayer> prayerLogic,
ICombinedKeyCrudLogic<CellGroupRoutineEventAttendee> dinnerLogic
) : base(crudLogic)
{
this.logic = logic;
this.prayerLogic = prayerLogic;
this.dinnerLogic = dinnerLogic;
}
// GET: api/CellGroupRoutineEvents
[HttpGet]
public CellGroupRoutineEvent GetComingEvent()
{
return logic.GetComingEvent();
}
[HttpGet]
public CellGroupRoutineEvent GetLastEvent()
{
return logic.GetLastEvent();
}
[HttpPost]
public int CreateOrUpdatePrayer(CellGroupRoutineEventPrayer p)
{
return prayerLogic.CreateOrUpdate(p);
}
[HttpPost]
public int CreateOrUpdateAttendees(CellGroupRoutineEventAttendee p)
{
return dinnerLogic.CreateOrUpdate(p);
}
}
[Route("[controller]/[action]")]
[ApiController]
public class CellGroupRoutineEventPrayerController : CombinedKeyApiControllerBase<CellGroupRoutineEventPrayer>
{
public CellGroupRoutineEventPrayerController(ICombinedKeyCrudLogic<CellGroupRoutineEventPrayer> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,16 @@
using Church.Net.Entity;
using Microsoft.AspNetCore.Mvc;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class ContributionController : ApiControllerBase<Contribution>
{
public ContributionController(ICrudLogic<Contribution> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,42 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.IO;
using System.Linq;
using WebAPI;
using WebAPI.Services.Interfaces;
namespace Church.Net.WebAPI.Controllers
{
[Route("[controller]")]
[ApiController]
public class FileListController : ControllerBase
{
private readonly ILoggingService loggingService;
public FileListController(ILoggingService loggingService)
{
this.loggingService = loggingService;
}
[HttpGet("{*filePath}")]
public ActionResult<string[]> Get(string filePath)
{
string folderRootPath = "";
string folderPath = "";
try
{
#if DEBUG
folderRootPath = "//ArkNAS/docker/ChurchAPI/App_Data/Files";
#else
folderRootPath = "/App_Data/Files";
#endif
folderPath = System.IO.Path.Combine(folderRootPath, filePath);
return Directory.GetFiles(folderPath).Select(s=>s.Replace(folderRootPath,"").Replace(filePath, "").Replace("\\","/")).ToArray();
}
catch (System.Exception ex)
{
loggingService.Error(ex);
return NotFound();
}
}
}
}
@@ -0,0 +1,40 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.IO;
using WebAPI;
using WebAPI.Services.Interfaces;
namespace Church.Net.WebAPI.Controllers
{
[Route("[controller]")]
[ApiController]
public class FilesController : ControllerBase
{
private readonly ILoggingService loggingService;
public FilesController(ILoggingService loggingService)
{
this.loggingService = loggingService;
}
[HttpGet("{*filePath}")]
public IActionResult Get(string filePath)
{
try
{
string folderRootPath = "";
#if DEBUG
folderRootPath = "//ArkNAS/docker/ChurchAPI/App_Data/Files";
#else
folderRootPath = "/App_Data/Files";
#endif
return PhysicalFile(System.IO.Path.Combine(folderRootPath, filePath), "image/jpeg");
}
catch (System.Exception ex)
{
loggingService.Error(ex);
return NotFound();
}
}
}
}
@@ -0,0 +1,57 @@
using Church.Net.WebAPI.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using WebAPI.Models.IceBreak;
using WebAPI;
using System.Linq;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace Church.Net.WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class GameRoomController : ControllerBase
{
private readonly GameRoomLogic gameRoomLogic;
public GameRoomController(GameRoomLogic gameRoomLogic)
{
this.gameRoomLogic = gameRoomLogic;
}
// GET: api/<GameRoomMessageController>
[HttpGet]
public IEnumerable<GameRoom> Get()
{
return gameRoomLogic.GameRooms;
}
// GET api/<GameRoomMessageController>/5
[HttpGet("{id}")]
public IEnumerable<IGamePlayer> Get(string roomId)
{
return gameRoomLogic.GameRooms.Where(r => r.Id == roomId).FirstOrDefault()?.Players;
}
// POST api/<GameRoomMessageController>
[HttpPost]
public void Post([FromBody] GamePlayer gamePlayer)
{
gameRoomLogic.CreateGameRoom(gamePlayer);
}
// PUT api/<GameRoomMessageController>/5
[HttpPut("{roomId}")]
public bool Put(string roomId, [FromBody] GamePlayer value)
{
return gameRoomLogic.UserJoinGameRoom(roomId, value);
}
// DELETE api/<GameRoomMessageController>/5
[HttpDelete("{id}")]
public void Delete(string id)
{
gameRoomLogic.UserLeave(new GamePlayer() { Id = id });
}
}
}
@@ -0,0 +1,55 @@
using Church.Net.WebAPI.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using WebAPI;
using WebAPI.Models.IceBreak;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace Church.Net.WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class GameRoomMessageController : ControllerBase
{
private readonly GameRoomLogic gameRoomLogic;
public GameRoomMessageController(GameRoomLogic gameRoomLogic)
{
this.gameRoomLogic = gameRoomLogic;
}
// GET: api/<GameRoomMessageController>
[HttpGet]
public IEnumerable<GameRoom> Get()
{
return gameRoomLogic.GameRooms;
}
// GET api/<GameRoomMessageController>/5
[HttpGet("{id}")]
public IEnumerable<IGamePlayer> Get(string roomId)
{
return gameRoomLogic.GameRooms.Where(r => r.Id == roomId).FirstOrDefault()?.Players;
}
// POST api/<GameRoomMessageController>
[HttpPost]
public void Post([FromBody] SignalRMessage message)
{
gameRoomLogic.SendMessage(message);
}
// PUT api/<GameRoomMessageController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/<GameRoomMessageController>/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
@@ -0,0 +1,18 @@
using Church.Net.Entity;
using Microsoft.AspNetCore.Mvc;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class HappinessCostController : ApiControllerBase<HappinessCost>
{
public HappinessCostController(ICrudLogic<HappinessCost> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,23 @@
using Church.Net.Entity;
using Church.Net.Entity.Messenger;
using LineMessaging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebAPI.Logics;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class HappinessWeekTaskController : ApiControllerBase<HappinessTask>
{
public HappinessWeekTaskController(ICrudLogic<HappinessTask> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Church.Net.DAL.EF;
using Church.Net.Entity;
using Church.Net.Utility;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Primitives;
using QRCoder;
using LineMessaging;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Text;
using WebAPI.Services;
using Jint.Native;
using WebAPI.Services.Interfaces;
using Church.Net.DAL.EFCoreDBF.Migrations;
using WebAPI.Logics;
using Church.Net.DAL.EFCoreDBF.Interface;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace WebAPI.Controllers
{
//[Route("[controller]")]
[ApiController]
[Route("[controller]/[action]")]
public class LineMessageController : ControllerBase
{
private readonly LineAutoBotService lineAutoBotService;
private readonly ILoggingService loggingService;
private readonly ICrudDAL<LineMessagingAccount> crudDAL;
private readonly PastoralDomainLogic pastoralDomainLogic;
public LineMessageController(
LineAutoBotService lineAutoBotService,
ILoggingService loggingService,
ICrudDAL<LineMessagingAccount> crudDAL,
PastoralDomainLogic pastoralDomainLogic
)
{
this.lineAutoBotService = lineAutoBotService;
this.loggingService = loggingService;
this.crudDAL = crudDAL;
this.pastoralDomainLogic = pastoralDomainLogic;
}
//private ChurchNetContext dbContext = new ChurchNetContext();
//// GET: api/<BestController>
//[HttpGet]
//public IEnumerable<string> Get()
//{
// return new string[] { "value2222", "value4" };
//}
//// GET api/<BestController>/5
//[HttpGet("{id}")]
//public HappinessBEST Get(string id)
//{
// var best = dbContext.HappinessBESTs.Include(b => b.HappinessGroup).ThenInclude(b => b.Weeks).FirstOrDefault(b => b.BestId == id);
// best.HappinessGroup.Weeks = best.HappinessGroup.Weeks.OrderBy(w => w.SEQ).ToList();
// return best;
//}
// POST api/<BestController>
[HttpPost]
public async Task PostFromLine(int seq, [FromBody] object jsonData)
{
//string txtPath = ServerUtils.MapPath("App_Data/LinePostRawLog.txt");
//System.IO.File.AppendAllText(txtPath, JsonConvert.SerializeObject(jsonData.ToString(), Formatting.Indented));
try
{
LineMessagingAccount lineAccount = crudDAL.GetAll(l => l.Seq == seq).FirstOrDefault();
if (lineAccount != null)
{
LineWebhookContent content = JsonConvert.DeserializeObject<LineWebhookContent>(jsonData.ToString());
await lineAutoBotService.AutoReply(lineAccount,content);
}
//this.loggingService.Log("PostFromLine");
}
catch (Exception ex)
{
this.loggingService.Error(ex);
}
//Cac4ac5a8d7fc52daa444d71dc7c360a9 方舟小組 GroupID
//Ca20e3b65aa58e676815eb13c3222591a 方舟小組同工 GroupID
//var test = new LineMessaging.();
//var test = new LineMessagingClient("WFAyMvMEZ86cfMJIAzE+yklUZGpeS/jFYTeL9a9O35QR83oNMmwaUJfyEe48Kegadz0BArDdBoySxs479U1pwTHtlyH+Sm4jqlz8BwukX/Hsa4D1fX03Qn4zFu7TwPFKWFXnZbWq89Yg0iNzjpfTNwdB04t89/1O/w1cDnyilFU=");
//test.PushMessage(value.To, new LineTextMessage() { Text = value.Message });
}
[HttpPut("{id}")]
public async void PushTextMessage(string id, [FromBody] LineMessage value)
{
var test = new LineMessagingClient();
await test.PushMessage(id, new LineTextMessage() { Text = value.Message });
}
[HttpGet]
public Task PushCommandMessage(string groupId, string command)
{
return lineAutoBotService.PushCommandMessage(pastoralDomainLogic.GetById(groupId), "#" + command);
}
}
public class LineMessage
{
public string To { get; set; }
public string Message { get; set; }
}
}
@@ -0,0 +1,48 @@
using Church.Net.Entity;
using Church.Net.Entity.Messenger;
using LineMessaging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebAPI.Logics;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class LineMessagingAccountController : ApiControllerBase<LineMessagingAccount>
{
public LineMessagingAccountController(LineMessagingAccountLogic logic) : base(logic)
{
}
[HttpGet]
public void RefreshAllQuota()
{
foreach (var item in logic.GetAll())
{
if (!string.IsNullOrWhiteSpace(item.ChatToken))
{
var lineMessegeClient = new LineMessagingClient(item.ChatToken);
item.TotalUsage = lineMessegeClient.GetTotalUsage().Result;
logic.Update(item);
}
}
}
}
[Route("[controller]/[action]")]
[ApiController]
public class LineClientController : ApiControllerBase<LineMessageClient>
{
public LineClientController(ICrudLogic<LineMessageClient> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,60 @@
using Church.Net.Entity;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebAPI.Logics.Interface;
using WebAPI.Services.Interfaces;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class LogController : ApiControllerBase<LogInfo>
{
private readonly ILoggingService loggingService;
public LogController(
ICrudLogic<LogInfo> logic,
ILoggingService loggingService
) : base(logic)
{
this.loggingService = loggingService;
}
[HttpPost]
public void PurgeBefore([FromBody] DateTime date)
{
logic.Delete(l => l.Time <= date.ToUniversalTime());
}
[Route("/error-development")]
public IActionResult HandleErrorDevelopment(
[FromServices] IHostEnvironment hostEnvironment)
{
if (!hostEnvironment.IsDevelopment())
{
return NotFound();
}
var exceptionHandlerFeature =
HttpContext.Features.Get<IExceptionHandlerFeature>()!;
this.loggingService.Error(exceptionHandlerFeature.Error, exceptionHandlerFeature.Path);
return Problem(
detail: exceptionHandlerFeature.Error.StackTrace,
title: exceptionHandlerFeature.Error.Message);
}
[Route("/error")]
public IActionResult HandleError()
{
var exceptionHandlerFeature =
HttpContext.Features.Get<IExceptionHandlerFeature>()!;
this.loggingService.Error(exceptionHandlerFeature.Error, exceptionHandlerFeature.Path);
return Problem();
}
}
}
@@ -0,0 +1,19 @@
using Church.Net.Entity;
using Church.Net.Entity.Games.MD2;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class MD2MobInfoController : ApiControllerBase<MobInfo>
{
public MD2MobInfoController(ICrudLogic<MobInfo> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,18 @@
using Church.Net.Entity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class MemberController : ApiControllerBase<FamilyMember>
{
public MemberController(ICrudLogic<FamilyMember> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,19 @@
using Church.Net.Entity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class NewVisitorController : ApiControllerBase<NewVisitor>
{
public NewVisitorController(ICrudLogic<NewVisitor> logic) : base(logic)
{
}
}
}
@@ -0,0 +1,243 @@
using Church.Net.DAL.EF;
using Church.Net.DAL.EFCoreDBF.Core;
using Church.Net.Entity;
using Church.Net.Utility;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NuGet.Common;
using NuGet.ProjectModel;
using System;
using System.IO;
using System.Linq;
using System.Net;
using WebAPI.Logics.Interface;
using WebAPI.ViewModel;
using static QRCoder.PayloadGenerator;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace WebAPI.Controllers
{
[ApiController]
public class PasswordLoginController : ControllerBase
{
private readonly ChurchNetContext churchNetContext;
private readonly ICrudLogic<FamilyMember> crudLogic;
private readonly ICombinedKeyCrudLogic<PastoralDomainMembers> relationLogic;
private readonly ICrudLogic<PastoralDomain> domainLogic;
// POST api/<PasswordLoginController>
public PasswordLoginController(
ICrudLogic<FamilyMember> crudLogic,
ICombinedKeyCrudLogic<PastoralDomainMembers> relationLogic,
ICrudLogic<PastoralDomain> domainLogic,
DatabaseOptions databaseOptions
)
{
this.crudLogic = crudLogic;
this.relationLogic = relationLogic;
this.domainLogic = domainLogic;
churchNetContext = databaseOptions.GetDbContext();
}
[HttpPost]
[Route("auth/login")]
public LoginTokenViewModel Login([FromBody] RegisterViewModel value)
{
FamilyMember member = null;
if (string.IsNullOrEmpty(value.OAuthType))
{
value.Email = value.Email.Trim().ToLower();
member = crudLogic.First(f => f.Password == value.Password && f.Email.ToLower() == value.Email.ToLower());
//member = this.churchNetContext.FamilyMembers
// .Where(f => f.Password == value.Password && f.Email.ToLower() == value.Email.ToLower()).FirstOrDefault();
}
return ToLoginTokenViewModel(member);
}
[HttpPost]
[Route("auth/sign-up")]
[Route("auth/oauth-login")]
public LoginTokenViewModel SignUp([FromBody] RegisterViewModel value)
{
FamilyMember member = null;
string loginToken = "";
if (!string.IsNullOrEmpty(value.OAuthType))
{
if (value.OAuthType == "google")
{
if (false == this.GetGoogleLoginInfo(ref value)) return null;
}
var userId = this.churchNetContext.FamilyMemberOAuths
.Where(f => f.OAuthType == value.OAuthType && f.OAuthAccessToken == value.AccessToken)
.Select(f => f.FamilyMemberId).FirstOrDefault();
if (string.IsNullOrEmpty(userId))
{
value.Email = value.Email.Trim().ToLower();
member = this.churchNetContext.FamilyMembers
.Where(m => m.Email.ToLower() == value.Email)
.FirstOrDefault();
if (member == null)
{
member = new FamilyMember()
{
Id = StringHelper.Get33BaseGuid(),
FirstName = value.FirstName,
LastName = value.LastName,
Email = value.Email,
AvatarImage = value.AvatarImage,
Password = StringHelper.Get33BaseGuid()
};
churchNetContext.Add(member);
}
else
{
member.AvatarImage = value.AvatarImage;
member.FirstName = value.FirstName;
member.LastName = value.LastName;
churchNetContext.Update(member);
}
churchNetContext.Add(new FamilyMemberOAuth()
{
FamilyMemberId = member.Id,
OAuthType = value.OAuthType,
OAuthAccessToken = value.AccessToken
});
churchNetContext.SaveChanges();
}
else
{
member = this.churchNetContext.FamilyMembers
.Where(f => f.Id == userId).FirstOrDefault();
}
}
else
{
value.Email = value.Email.Trim().ToLower();
if (!this.churchNetContext.FamilyMembers
.Any(f => f.Email == value.Email))
{
member = new FamilyMember()
{
Id = StringHelper.Get33BaseGuid(),
FirstName = value.FirstName,
LastName = value.LastName,
Email = value.Email,
AvatarImage = value.AvatarImage,
Password = value.Password
};
churchNetContext.Add(member);
churchNetContext.SaveChanges();
}
}
return ToLoginTokenViewModel(member);
}
[HttpPost]
[Route("auth/request-pass")]
public void RequestPassword([FromBody] RegisterViewModel value)
{
}
[HttpPost]
[Route("auth/reset-pass")]
public void ResetPassword([FromBody] RegisterViewModel value)
{
}
[HttpPost]
[Route("auth/loginwithtoken")]
public LoginTokenViewModel LoginWithToken([FromBody] LoginTokenViewModel value)
{
var memberId = TokenHelper.GetUserIdFromToken(value.Token);
if (!string.IsNullOrWhiteSpace(memberId))
{
var member = crudLogic.First(f => f.Id == memberId);
//var member = this.churchNetContext.FamilyMembers
// .Where(f => f.Id == memberId).FirstOrDefault();
return ToLoginTokenViewModel(member);
}
return null;
}
private LoginTokenViewModel ToLoginTokenViewModel(FamilyMember member)
{
if (member != null)
{
DateTime expiredTime = DateTime.Now.AddDays(30);
string token = TokenHelper.GenerateToken(member.Id, expiredTime);
var cellGroupId = churchNetContext.PastoralDomainMembers.Where(d => d.FamilyMemberId == member.Id).Select(d => d.PastoralDomainId).FirstOrDefault();
PastoralDomain cellGroup;
if (string.IsNullOrEmpty(cellGroupId))
{
cellGroup = churchNetContext.PastoralDomains.First();
relationLogic.Create(new PastoralDomainMembers(cellGroup.Id, member.Id));
}
else
{
cellGroup = churchNetContext.PastoralDomains.Where(g=>g.Id== cellGroupId).First();
}
return new LoginTokenViewModel()
{
MemberId = member.Id,
FirstName = member.FirstName,
LastName = member.LastName,
AvatarImage = member.AvatarImage,
Email = member.Email,
Token = token,
TokenExpireTime = expiredTime,
Role = member.Role,
CellGroup= cellGroup
};
}
return null;
}
private bool GetGoogleLoginInfo(ref RegisterViewModel model)
{
string uri = $"https://www.googleapis.com/oauth2/v2/userinfo?access_token={model.AccessToken}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
var obj = JsonConvert.DeserializeObject<JObject>(result);
if (obj.TryGetValue("email", out JToken value))
{
model.Email = ((string)value).ToLower().Trim();
model.FirstName = obj.GetValue<string>("given_name");
model.LastName = obj.GetValue<string>("family_name");
model.AvatarImage = obj.GetValue<string>("picture");
model.AccessToken = obj.GetValue<string>("id");
return true;
}
}
}
catch (Exception)
{
}
return false;
}
}
}
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Church.Net.Entity;
using WebAPI.Logics;
using WebAPI.Logics.Interface;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace WebAPI.Controllers
{
[Route("[controller]/[action]")]
[Authorize]
[ApiController]
public class PastoralDomainController : ApiControllerBase<PastoralDomain>
{
private readonly PastoralDomainLogic logic;
public PastoralDomainController(PastoralDomainLogic logic) : base(logic)
{
this.logic = logic;
}
[HttpGet]
public Task<IEnumerable<PastoralDomain>> GetCurrentUserPastoralDomain()
{
return Task.Run(() =>
{
return logic.GetCurrentUserPastoralDomain();
});
}
}
[Route("[controller]/[action]")]
[ApiController]
[Authorize]
public class DomainMemberShipController : CombinedKeyApiControllerBase<PastoralDomainMembers>
{
public DomainMemberShipController(ICombinedKeyCrudLogic<PastoralDomainMembers> logic) : base(logic)
{
}
[HttpPost]
public int AssignCellGroups(IEnumerable<PastoralDomainMembers> relations)
{
logic.Delete(r => relations.Any(rr => (r.FamilyMemberId == rr.FamilyMemberId)));
foreach (var relation in relations)
{
//logic.Delete(r => r.FamilyMemberId == relation.FamilyMemberId);
logic.Create(relation);
}
return 1;
}
[HttpGet]
public int AddMemberIntoGroup(string domainId, string memberId)
{
return logic.CreateOrUpdate(new PastoralDomainMembers() { PastoralDomainId = domainId, FamilyMemberId = memberId });
}
[HttpGet]
public int RemoveMemberFromGroup(string domainId, string memberId)
{
return logic.Delete(r => r.PastoralDomainId == domainId && r.FamilyMemberId == memberId);
}
[HttpPost]
public int UpdateMembersInGroup(PastoralDomain domain)
{
logic.Delete(r => r.PastoralDomainId == domain.Id);
foreach (var member in domain.FamilyMembers)
{
//logic.Delete(r => r.FamilyMemberId == relation.FamilyMemberId);
logic.Create(new PastoralDomainMembers() { PastoralDomainId = domain.Id, FamilyMemberId = member.Id });
}
return 1;
}
}
}
@@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Church.Net.Utility;
using LineMessaging;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using WebAPI.Logics;
using WebAPI.Services;
using static System.Net.Mime.MediaTypeNames;
using WebAPI.Services.Interfaces;
using WebAPI.Logics.Interface;
namespace WebAPI.Controllers
{
[ApiController]
[Route("[controller]/[action]")]
public class PingController : ControllerBase
{
private readonly IEnumerable<IAutoReplyCommand> autoReplyCommands;
private readonly PastoralDomainLogic pastoralDomainLogic;
private readonly LineAutoBotService lineAutoBotService;
public PingController(VideoDownloadLogic videoDownloadLogic,
IEnumerable<IAutoReplyCommand> autoReplyCommands
)
{
VideoDownloadLogic = videoDownloadLogic;
this.autoReplyCommands = autoReplyCommands;
}
public VideoDownloadLogic VideoDownloadLogic { get; }
[HttpGet]
public List<Controller> GetEndpoints()
{
//using (var fileStream = new FileStream(ServerUtils.MapPath("Church/Test.mp4"), FileMode.Create))
//{
//}
//await Task.Run(() => {
//this.VideoDownloadLogic.Download(@"https://www.youtube.com/watch?v=nJBLeMrhu9w", @"\\ArkNAS\Church\Test.mp4");
//});
Console.WriteLine($"Self GetEndpoints: {DateTime.Now}");
string @namespace = this.GetType().Namespace;
Type ApiControllerType = typeof(ControllerBase);
IEnumerable<Type> controllers = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => t.Namespace == @namespace && ApiControllerType.IsAssignableFrom(t))
;
HashSet<string> baseMethods = new HashSet<string>(ApiControllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance).Select(mi => mi.Name));
List<Controller> _controllers = new List<Controller>();
foreach (var controller in controllers)
{
Controller _controller = new Controller { Name = controller.Name.Replace("Controller", "") };
foreach (var methodInfo in controller.GetMethods(BindingFlags.Public | BindingFlags.Instance))
{
if (baseMethods.Contains(methodInfo.Name)) continue;
try
{
bool isGet = methodInfo.GetCustomAttributes(typeof(HttpGetAttribute), false).Length > 0;
bool isPost = methodInfo.GetCustomAttributes(typeof(HttpPostAttribute), false).Length > 0;
bool isDelete = methodInfo.GetCustomAttributes(typeof(HttpDeleteAttribute), false).Length > 0;
if (isGet || isPost || isDelete)
{
Endpoint _endpoint = new Endpoint
{
Name = methodInfo.Name,
Method = isGet ? "GET" : (isPost ? "POST" : (isDelete ? "DELETE" : "UNKNOWN")),
Inputs = methodInfo.GetParameters().Select(m => new Input() { Name = m.Name }).ToArray(),
ReturnType = methodInfo.ReturnType,
//MethodInfo = methodInfo,
};
//_endpoint.HasDocString = HasDocString(_endpoint);
_controller.Endpoints.Add(_endpoint);
}
}
catch (Exception ex)
{
}
}
_controllers.Add(_controller);
}
return _controllers;
}
[HttpGet]
public async void TestMessage()
{
//\\ArkNAS\Church\WorshipVideo
//this.VideoDownloadLogic.Download(@"https://www.youtube.com/watch?v=K2bdSYim7uI", @"\\ArkNAS\home\Test.mp4");
var test = new LineMessagingClient();
string text = "$$$$Menu Item";
var textMessage = new LineTextMessage() { Text = text, Emojis = new List<Emoji>() };
textMessage.AddEmoji("$$", "5ac1bfd5040ab15980c9b435", "002");
var templateMessage = new LineTemplateMessage<ButtonTemplateObject>();
var addPrayerBtn = new UriAction()
{
Uri = "https://happiness.tours/CellGroup/prayer",
Label = "Prayer"
};
templateMessage.AltText = "代禱事項";
templateMessage.Template.DefaultAction = addPrayerBtn;
templateMessage.Template.ThumbnailImageUrl = "https://dailyverses.net/images/tc/cuv/matthew-21-22-3.jpg";
templateMessage.Template.Title = "代禱事項";
templateMessage.Template.Text = "Chris" + Environment.NewLine + "Testwerewiorjowerjiowejiro, erjaiworjweiorjioawereaw";
templateMessage.Template.Actions = new List<ILineAction>();
templateMessage.Template.Actions.Add(addPrayerBtn);
await test.PushMessage(EnumHelper.EnumToDescriptionString(LineGroup.Chris), textMessage);
}
[HttpGet]
public string[] GetFiles(string path)
{
return Directory.GetFiles("/App_Data/" + path);
}
public class Controller
{
public string Name { get; set; }
public List<Endpoint> Endpoints { get; set; } = new List<Endpoint>();
}
public class Endpoint
{
public string Name { get; set; }
public string Method { get; set; }
public Input[] Inputs { get; set; }
public Type ReturnType { get; set; }
public MethodInfo MethodInfo { get; set; }
public bool HasDocString { get; set; }
}
public partial class Input
{
public string Name { get; set; }
public long Position { get; set; }
}
}
}
@@ -0,0 +1,93 @@
using Church.Net.Utility;
using Microsoft.AspNetCore.Mvc;
using QRCoder;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Processing;
using System.IO;
using System.Threading.Tasks;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace Church.Net.WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class QRCodeController : ControllerBase
{
// GET api/<QRCodeController>/5
[HttpGet]
public async Task<IActionResult> Get(string content,int size)
{
QRCodeGenerator gen = new QRCodeGenerator();
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode(content, QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
var qrCodeImage = qrCode.GetGraphic(size);
//string qrCodeImagePath = "/App_Data/ScaneMeQrCode.png";
//var backgroundBitmap = SixLabors.ImageSharp.Image.Load(qrCodeImagePath);
//string qrCodeImagePath = Environment.GetEnvironmentVariable("AppData");
//HttpContext.Current.Server.MapPath("~/App_Data/");
//var fullPath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data/ScaneMeQrCode.png");
//System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data/yourXmlFile.xml");
//int positionLeft = 0;
//int positionTop = 0;
//var best = logic.GetById(id);
//if (best != null)
//{
// using (var memoryStream = new MemoryStream())
// {
// //fileStream.CopyTo(memoryStream);
// var image = Superimpose(best.Name, backgroundBitmap, qrCodeImage, 10, 32);
// image.Scalling(75);
// image.SaveAsPng(memoryStream);
// byte[] byteImage = memoryStream.ToArray();
// return File(byteImage, "image/png");
// }
//}
using (var memoryStream = new MemoryStream())
{
qrCodeImage.SaveAsJpeg(memoryStream);
return File(memoryStream.ToArray(), "image/jpeg");
}
}
private Font arialFont;
[NonAction]
public Image Superimpose(string bestName, Image largeBmp, Image smallBmp, int? x = null, int? y = null)
{
FontCollection collection = new();
FontFamily family = collection.Add("/App_Data/arial.ttf");
arialFont = family.CreateFont(12, FontStyle.Italic);
//Graphics g = Graphics.FromImage(largeBmp);
//g.CompositingMode = CompositingMode.SourceOver;
//smallBmp.MakeTransparent();
int margin = 5;
if (!x.HasValue)
{
x = largeBmp.Width - smallBmp.Width - margin;
}
if (!y.HasValue)
{
y = largeBmp.Height - smallBmp.Height - margin;
}
var scale = 0.8;
var scaleWidth = (int)(smallBmp.Width * scale);
var scaleHeight = (int)(smallBmp.Height * scale);
largeBmp.Mutate(x => x.DrawText(bestName, arialFont, Color.Black, new PointF(10, 10)));
smallBmp.Scalling(80);
largeBmp.Mutate(ctx => ctx.DrawImage(smallBmp, new Point(x.Value, y.Value), 1f));
return largeBmp;
}
}
}
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace WebAPI.Controllers
{
[ApiController]
[Route("[controller]")]
public class VersionController : ControllerBase
{
[HttpGet]
public string Get()
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);
string version = fvi.FileVersion;
return version;
}
}
}
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace WebAPI.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using WebAPI.Hubs;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace WebAPI.Controllers
{
[Route("[controller]")]
[ApiController]
public class WhoIsSpyController : ControllerBase
{
private readonly IHubContext<WhoIsSpyHub> hubContext;
public WhoIsSpyController(IHubContext<WhoIsSpyHub> hubContext)
{
this.hubContext = hubContext;
}
// GET: api/<WhoIsSpyController>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<WhoIsSpyController>/5
[HttpGet("{id}")]
public string Get(string id)
{
return "value";
}
// POST api/<WhoIsSpyController>
[HttpPost]
public void Post([FromBody] string value)
{
hubContext.Clients.All.SendAsync("");
}
// PUT api/<WhoIsSpyController>/5
[HttpPut("{id}")]
public void Put(string id, [FromBody] string value)
{
}
// DELETE api/<WhoIsSpyController>/5
[HttpDelete("{id}")]
public void Delete(string id)
{
}
}
}