This commit is contained in:
Chris Chen 2023-08-20 11:28:47 -07:00
parent 2c491b63de
commit ad0bc0e49b
78 changed files with 3640 additions and 5639 deletions

View File

@ -11,8 +11,6 @@ using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Chruch.Net.Models;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net
{
@ -34,78 +32,4 @@ namespace Chruch.Net
}
}
// 設定此應用程式中使用的應用程式使用者管理員。UserManager 在 ASP.NET Identity 中定義且由應用程式中使用。
public class ApplicationUserManager : UserManager<FamilyMember>
{
public ApplicationUserManager(IUserStore<FamilyMember> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<FamilyMember>(context.Get<ChurchNetContext>()));
// 設定使用者名稱的驗證邏輯
manager.UserValidator = new UserValidator<FamilyMember>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// 設定密碼的驗證邏輯
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// 設定使用者鎖定詳細資料
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// 註冊雙因素驗證提供者。此應用程式使用手機和電子郵件接收驗證碼以驗證使用者
// 您可以撰寫專屬提供者,並將它外掛到這裡。
manager.RegisterTwoFactorProvider("電話代碼", new PhoneNumberTokenProvider<FamilyMember>
{
MessageFormat = "您的安全碼為 {0}"
});
manager.RegisterTwoFactorProvider("電子郵件代碼", new EmailTokenProvider<FamilyMember>
{
Subject = "安全碼",
BodyFormat = "您的安全碼為 {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<FamilyMember>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
// 設定在此應用程式中使用的應用程式登入管理員。
public class ApplicationSignInManager : SignInManager<FamilyMember, string>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(FamilyMember user)
{
return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
}

View File

@ -6,8 +6,6 @@ using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Owin;
using Chruch.Net.Models;
using Church.Net.DAL.EF;
using Church.Net.Entity;
using Microsoft.AspNet.Identity.EntityFramework;
namespace Chruch.Net
@ -18,26 +16,10 @@ namespace Chruch.Net
public void ConfigureAuth(IAppBuilder app)
{
// 設定資料庫內容、使用者管理員和登入管理員,以針對每個要求使用單一執行個體
app.CreatePerOwinContext(ChurchNetContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// 讓應用程式使用 Cookie 儲存已登入使用者的資訊
// 並使用 Cookie 暫時儲存使用者利用協力廠商登入提供者登入的相關資訊;
// 在 Cookie 中設定簽章
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// 讓應用程式在使用者登入時驗證安全性戳記。
// 這是您變更密碼或將外部登入新增至帳戶時所使用的安全性功能。
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, FamilyMember>(
validateInterval: TimeSpan.FromDays(300),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// 讓應用程式在雙因素驗證程序中驗證第二個因素時暫時儲存使用者資訊。
@ -72,70 +54,8 @@ namespace Chruch.Net
private void CreateRolesandUsers()
{
ChurchNetContext context = new ChurchNetContext();
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var UserManager = new UserManager<FamilyMember>(new UserStore<FamilyMember>(context));
// In Startup iam creating first Admin Role and creating a default Admin User
if (!roleManager.RoleExists("Admin"))
{
// first we create Admin rool
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "Admin";
roleManager.Create(role);
//Here we create a Admin super user who will maintain the website
var user = new FamilyMember();
user.UserName = "chris";
user.Email = "yuanson.chen@gmail.com";
user.Birthday = new DateTime(1990, 01, 29);
user.DateOfWalkIn = new DateTime(2018, 05, 25);
string userPWD = "6262263816";
var chkUser = UserManager.Create(user, userPWD);
//Add default User to Role Admin
if (chkUser.Succeeded)
{
var result1 = UserManager.AddToRole(user.Id, "Admin");
}
}
// creating Creating Manager role
if (!roleManager.RoleExists("DirectorPastor"))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "DirectorPastor";
roleManager.Create(role);
}
if (!roleManager.RoleExists("Pastor"))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "Pastor";
roleManager.Create(role);
}
// creating Creating Employee role
if (!roleManager.RoleExists("FamilyMember"))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "FamilyMember";
roleManager.Create(role);
}
if (!roleManager.RoleExists("CellGroupLeader"))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "CellGroupLeader";
roleManager.Create(role);
}
}
}
}

View File

@ -1,344 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net.Areas.English.Controllers
{
public class VocabulariesController : Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: English/Vocabularies
public ActionResult Index()
{
var query = db.Vocabulary.Where(v => v.PracticeStage !=Enumeration.PracticeStage.FlashCard);
return View(query.OrderBy(v => v.PracticeStage).ThenByDescending(v=>v.InsertDate).ToList());
}
// GET: English/Vocabularies/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Vocabulary vocabulary = db.Vocabulary.Find(id);
if (vocabulary == null)
{
return HttpNotFound();
}
return View(vocabulary);
}
// GET: English/Vocabularies/Create
public ActionResult Create()
{
return View();
}
// POST: English/Vocabularies/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Vocabulary vocabulary)
{
if (ModelState.IsValid)
{
vocabulary.Word = vocabulary.Word.ToLower();
vocabulary.Word = vocabulary.Word.Substring(0, 1).ToUpper() + vocabulary.Word.Substring(1, vocabulary.Word.Length - 1);
vocabulary.InsertDate = DateTime.Now;
vocabulary.PracticeDate = DateTime.Now;
vocabulary.PracticeStage = Enumeration.PracticeStage.Select;
if (vocabulary.PartOfSpeech == Enumeration.PartsOfSpeech.Verbs)
{
vocabulary.VerbPast = vocabulary.Word + "ed";
vocabulary.VerbParticiple = vocabulary.Word + "ed";
}
db.Vocabulary.Add(vocabulary);
db.SaveChanges();
return RedirectToAction("Create");
}
return View(vocabulary);
}
public ActionResult Memorized()
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.FirstOrDefault(v => v.PracticeDate <= DateTime.Today && (v.PracticeStage == Enumeration.PracticeStage.Select || v.PracticeStage == Enumeration.PracticeStage.Memorized));
if (vocabulary != null)
{
vocabulary.PracticeTimes = 5;
return View(vocabulary);
}
else
{
return RedirectToAction("Index");
}
}
// POST: English/Vocabularies/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
public ActionResult MemorizedNext(int id)
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.First(v => v.Id == id);
vocabulary.PracticeDate = DateTime.Now;
vocabulary.PracticeStage = Enumeration.PracticeStage.Visualize;
db.Entry(vocabulary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Memorized");
}
public ActionResult Visualize()
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.FirstOrDefault(v => v.PracticeDate <= DateTime.Today && v.PracticeStage ==Enumeration.PracticeStage.Visualize);
if (vocabulary != null)
{
vocabulary.PracticeTimes = 3;
return View(vocabulary);
}
else
{
return RedirectToAction("Index");
}
}
// POST: English/Vocabularies/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
public ActionResult VisualizeNext(int id)
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.First(v => v.Id == id);
vocabulary.PracticeDate = DateTime.Now;
vocabulary.PracticeStage = vocabulary.PracticeStage + 1;
db.Entry(vocabulary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Visualize");
}
public ActionResult Apply()
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.FirstOrDefault(v => v.PracticeDate <= DateTime.Today && v.PracticeStage==Enumeration.PracticeStage.Apply);
if (vocabulary != null)
{
vocabulary.PracticeTimes = 2;
return View(vocabulary);
}
else
{
return RedirectToAction("Index");
}
}
// POST: English/Vocabularies/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
public ActionResult ApplyNext(Vocabulary model)
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.First(v => v.Id == model.Id);
vocabulary.PracticeDate = DateTime.Now;
vocabulary.PracticeStage = vocabulary.PracticeStage + 1;
vocabulary.PracticeSentence = model.PracticeSentence;
db.Entry(vocabulary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Apply");
}
public ActionResult Review()
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.FirstOrDefault(v => v.PracticeDate <= DateTime.Today && v.PracticeStage == Enumeration.PracticeStage.Review);
if (vocabulary != null)
{
vocabulary.PracticeTimes = 1;
return View(vocabulary);
}
else
{
return RedirectToAction("Index");
}
}
// POST: English/Vocabularies/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
public ActionResult ReviewNext(int id)
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.First(v => v.Id == id);
vocabulary.PracticeDate = DateTime.Now;
vocabulary.PracticeStage = vocabulary.PracticeStage + 1;
db.Entry(vocabulary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Review");
}
public ActionResult ReviewRepracticeNext(int id)
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.First(v => v.Id == id);
vocabulary.PracticeDate = DateTime.Now;
vocabulary.PracticeStage = Enumeration.PracticeStage.Select;
db.Entry(vocabulary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Review");
}
// GET: English/Vocabularies/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Vocabulary vocabulary = db.Vocabulary.Find(id);
if (vocabulary == null)
{
return HttpNotFound();
}
return View(vocabulary);
}
// POST: English/Vocabularies/Edit/5
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Vocabulary vocabulary)
{
if (ModelState.IsValid)
{
vocabulary.Word = vocabulary.Word.ToLower();
vocabulary.Word = vocabulary.Word.Substring(0, 1).ToUpper() + vocabulary.Word.Substring(1, vocabulary.Word.Length - 1);
db.Entry(vocabulary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vocabulary);
}
// GET: English/Vocabularies/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Vocabulary vocabulary = db.Vocabulary.Find(id);
if (vocabulary == null)
{
return HttpNotFound();
}
return View(vocabulary);
}
// POST: English/Vocabularies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Vocabulary vocabulary = db.Vocabulary.Find(id);
db.Vocabulary.Remove(vocabulary);
db.SaveChanges();
return RedirectToAction("Index");
}
public ActionResult FlashCard()
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.OrderBy(v=>v.FlashCardTimes).FirstOrDefault(v => v.PracticeStage == Enumeration.PracticeStage.FlashCard);
if (vocabulary != null)
{
return View(vocabulary);
}
else
{
return RedirectToAction("Index");
}
}
public ActionResult FlashCardNext(int id)
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.First(v => v.Id == id);
vocabulary.PracticeDate = DateTime.Now;
vocabulary.FlashCardTimes +=1;
db.Entry(vocabulary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("FlashCard");
}
public ActionResult FlashCardForgot(int id)
{
Vocabulary vocabulary;
vocabulary = db.Vocabulary.First(v => v.Id == id);
vocabulary.PracticeDate = DateTime.Now;
vocabulary.FlashCardTimes =0;
vocabulary.PracticeStage = Enumeration.PracticeStage.Select;
db.Entry(vocabulary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("FlashCard");
}
public ActionResult UpdateDB()
{
db.Vocabulary.Where(v => v.PracticeMemorized == false).ToList().ForEach(v => v.PracticeStage = Enumeration.PracticeStage.Memorized);
db.Vocabulary.Where(v => v.PracticeMemorized == true && v.PracticeVisualize == false).ToList().ForEach(v => v.PracticeStage = Enumeration.PracticeStage.Visualize);
db.Vocabulary.Where(v => v.PracticeMemorized == true && v.PracticeVisualize == true && v.PracticeApply == false).ToList().ForEach(v => v.PracticeStage = Enumeration.PracticeStage.Apply);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
protected override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)
{
ViewBag.P_Select = db.Vocabulary.Count(v => v.PracticeStage == Enumeration.PracticeStage.Select );
ViewBag.P_Memorized = db.Vocabulary.Count(v => v.PracticeStage == Enumeration.PracticeStage.Memorized && v.PracticeDate < DateTime.Today);
ViewBag.P_Visualize = db.Vocabulary.Count(v => v.PracticeStage == Enumeration.PracticeStage.Visualize && v.PracticeDate < DateTime.Today);
ViewBag.P_Apply = db.Vocabulary.Count(v => v.PracticeStage == Enumeration.PracticeStage.Apply && v.PracticeDate < DateTime.Today);
ViewBag.P_Review = db.Vocabulary.Count(v => v.PracticeStage == Enumeration.PracticeStage.Review && v.PracticeDate < DateTime.Today);
}
}
}

View File

@ -1,24 +0,0 @@
using System.Web.Mvc;
namespace Chruch.Net.Areas.English
{
public class EnglishAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "English";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"English_default",
"English/{controller}/{action}/{id}",
new { controller= "Vocabularies", action = "Index", id = UrlParameter.Optional }
);
}
}
}

View File

@ -1,705 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title - English Vocalbulary</title>
@Scripts.Render("~/bundles/modernizr")
<!-- Required Meta Tags Always Come First -->
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<!-- Favicon -->
<link rel="shortcut icon" href="/favicon.ico">
<!-- Google Fonts -->
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans%3A400%2C300%2C500%2C600%2C700%7CPlayfair+Display%7CRoboto%7CRaleway%7CSpectral%7CRubik">
<!-- CSS Global Compulsory -->
@Styles.Render("~/Content/bootstrap")
@Styles.Render("~/Content/DashboardCss")
</head>
<body>
@Scripts.Render("~/bundles/jquery")
<!-- Header -->
<header id="js-header" class="u-header u-header--sticky-top">
<div class="u-header__section u-header__section--admin-dark g-min-height-65">
<nav class="navbar no-gutters g-pa-0">
<div class="col-auto d-flex flex-nowrap u-header-logo-toggler g-py-12">
<!-- Logo -->
<a href="#" class="align-self-center d-flex g-hidden-xs-down g-line-height-1 g-ml-40 g-mt-5 navbar-brand py-0">
<img src="/Images/logo-light.png" class="g-height-50 img-fluid">
</a>
<!-- End Logo -->
<!-- Sidebar Toggler -->
<a class="js-side-nav u-header__nav-toggler d-flex align-self-center ml-auto" href="#!" data-hssm-class="u-side-nav--mini u-sidebar-navigation-v1--mini" data-hssm-body-class="u-side-nav-mini" data-hssm-is-close-all-except-this="true" data-hssm-target="#sideNav">
<i class="hs-admin-align-left"></i>
</a>
<!-- End Sidebar Toggler -->
</div>
<!-- Top Search Bar -->
<form id="searchMenu" class="u-header--search col-sm g-py-12 g-ml-15--sm g-ml-20--md g-mr-10--sm" aria-labelledby="searchInvoker" action="#!">
<div class="input-group g-max-width-450">
<input class="form-control form-control-md g-rounded-4" type="text" placeholder="Enter search keywords">
<button type="submit" class="btn u-btn-outline-primary g-brd-none g-bg-transparent--hover g-pos-abs g-top-0 g-right-0 d-flex g-width-40 h-100 align-items-center justify-content-center g-font-size-18 g-z-index-2">
<i class="hs-admin-search"></i>
</button>
</div>
</form>
<!-- End Top Search Bar -->
<!-- Messages/Notifications/Top Search Bar/Top User -->
<div class="col-auto d-flex g-py-12 g-pl-40--lg ml-auto">
<!-- Top Messages -->
<div class="g-pos-rel g-hidden-sm-down g-mr-5">
<a class="d-block text-uppercase u-header-icon-v1 g-pos-rel g-width-40 g-height-40 rounded-circle g-font-size-20" href="@Url.Action("Create","Vocabularies")">
@if (ViewBag.P_Select > 0)
{
<span class="u-badge-v1 g-top-7 g-right-7 g-width-18 g-height-18 g-bg-primary g-font-size-10 g-color-white rounded-circle p-0">@ViewBag.P_Select</span>
}
<i class="hs-admin-search g-absolute-centered"></i>
</a>
</div>
<div class="g-pos-rel g-hidden-sm-down g-mr-5">
<a class="d-block text-uppercase u-header-icon-v1 g-pos-rel g-width-40 g-height-40 rounded-circle g-font-size-20" href="@Url.Action("Memorized","Vocabularies")">
@if (ViewBag.P_Memorized > 0)
{
<span class="u-badge-v1 g-top-7 g-right-7 g-width-18 g-height-18 g-bg-primary g-font-size-10 g-color-white rounded-circle p-0">@ViewBag.P_Memorized</span>
}
<i class="hs-admin-book g-absolute-centered"></i>
</a>
</div>
<div class="g-pos-rel g-hidden-sm-down g-mr-5">
<a class="d-block text-uppercase u-header-icon-v1 g-pos-rel g-width-40 g-height-40 rounded-circle g-font-size-20" href="@Url.Action("Visualize","Vocabularies")">
@if (ViewBag.P_Visualize > 0)
{
<span class="u-badge-v1 g-top-7 g-right-7 g-width-18 g-height-18 g-bg-primary g-font-size-10 g-color-white rounded-circle p-0">@ViewBag.P_Visualize</span>
}
<i class="hs-admin-gallery g-absolute-centered"></i>
</a>
</div>
<div class="g-pos-rel g-hidden-sm-down g-mr-5">
<a class="d-block text-uppercase u-header-icon-v1 g-pos-rel g-width-40 g-height-40 rounded-circle g-font-size-20" href="@Url.Action("Apply","Vocabularies")">
@if (ViewBag.P_Apply > 0)
{
<span class="u-badge-v1 g-top-7 g-right-7 g-width-18 g-height-18 g-bg-primary g-font-size-10 g-color-white rounded-circle p-0">@ViewBag.P_Apply</span>
}
<i class="hs-admin-comment-alt g-absolute-centered"></i>
</a>
</div>
<div class="g-pos-rel g-hidden-sm-down g-mr-5">
<a class="d-block text-uppercase u-header-icon-v1 g-pos-rel g-width-40 g-height-40 rounded-circle g-font-size-20" href="@Url.Action("Review","Vocabularies")">
@if (ViewBag.P_Review > 0)
{
<span class="u-badge-v1 g-top-7 g-right-7 g-width-18 g-height-18 g-bg-primary g-font-size-10 g-color-white rounded-circle p-0">@ViewBag.P_Review</span>
}
<i class="hs-admin-loop g-absolute-centered"></i>
</a>
</div>
<div class="g-pos-rel g-hidden-sm-down g-mr-5">
<a class="d-block text-uppercase u-header-icon-v1 g-pos-rel g-width-40 g-height-40 rounded-circle g-font-size-20" href="@Url.Action("FlashCard","Vocabularies")">
@if (ViewBag.P_Review > 0)
{
<span class="u-badge-v1 g-top-7 g-right-7 g-width-18 g-height-18 g-bg-primary g-font-size-10 g-color-white rounded-circle p-0">@ViewBag.P_Review</span>
}
<i class="hs-admin-loop g-absolute-centered"></i>
</a>
</div>
<!-- End Top Messages -->
</div>
<!-- End Messages/Notifications/Top Search Bar/Top User -->
<!-- Top Activity Toggler -->
<a id="activityInvoker" class="text-uppercase u-header-icon-v1 g-pos-rel g-width-40 g-height-40 rounded-circle g-font-size-20" href="#!" aria-controls="activityMenu" aria-haspopup="true" aria-expanded="false" data-dropdown-event="click" data-dropdown-target="#activityMenu"
data-dropdown-type="css-animation" data-dropdown-animation-in="fadeInRight" data-dropdown-animation-out="fadeOutRight" data-dropdown-duration="300">
<i class="hs-admin-align-right g-absolute-centered"></i>
</a>
<!-- End Top Activity Toggler -->
</nav>
<!-- Top Activity Panel -->
<div id="activityMenu" class="js-custom-scroll u-header-sidebar g-pos-fix g-top-0 g-left-auto g-right-0 g-z-index-4 g-width-300 g-width-400--sm g-height-100vh" aria-labelledby="activityInvoker">
<div class="u-header-dropdown-bordered-v1 g-pa-20">
<a id="activityInvokerClose" class="pull-right g-color-lightblue-v2" href="#!" aria-controls="activityMenu" aria-haspopup="true" aria-expanded="false" data-dropdown-event="click" data-dropdown-target="#activityMenu" data-dropdown-type="css-animation"
data-dropdown-animation-in="fadeInRight" data-dropdown-animation-out="fadeOutRight" data-dropdown-duration="300">
<i class="hs-admin-close"></i>
</a>
<h4 class="text-uppercase g-font-size-default g-letter-spacing-0_5 g-mr-20 g-mb-0">Activity</h4>
</div>
<!-- Activity Short Stat. -->
<section class="g-pa-20">
<div class="media align-items-center u-link-v5 g-color-white">
<div class="media-body align-self-center g-line-height-1_3 g-font-weight-300 g-font-size-40">
624 <span class="g-font-size-16">+3%</span>
</div>
<div class="d-flex align-self-center g-font-size-25 g-line-height-1 g-color-lightblue-v3 ml-auto">$49,000</div>
<div class="d-flex align-self-center g-ml-8">
<svg class="g-fill-white-opacity-0_5" width="12px" height="20px" viewBox="0 0 12 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(-21.000000, -751.000000)">
<g transform="translate(0.000000, 64.000000)">
<g transform="translate(20.000000, 619.000000)">
<g transform="translate(1.000000, 68.000000)">
<polygon points="6 20 0 13.9709049 0.576828937 13.3911999 5.59205874 18.430615 5.59205874 0 6.40794126 0 6.40794126 18.430615 11.4223552 13.3911999 12 13.9709049"></polygon>
</g>
</g>
</g>
</g>
</svg>
<svg class="g-fill-lightblue-v3" width="12px" height="20px" viewBox="0 0 12 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(-33.000000, -751.000000)">
<g transform="translate(0.000000, 64.000000)">
<g transform="translate(20.000000, 619.000000)">
<g transform="translate(1.000000, 68.000000)">
<polygon transform="translate(18.000000, 10.000000) scale(1, -1) translate(-18.000000, -10.000000)" points="18 20 12 13.9709049 12.5768289 13.3911999 17.5920587 18.430615 17.5920587 0 18.4079413 0 18.4079413 18.430615 23.4223552 13.3911999 24 13.9709049"></polygon>
</g>
</g>
</g>
</g>
</svg>
</div>
</div>
<span class="g-font-size-16">Transactions</span>
</section>
<!-- End Activity Short Stat. -->
<!-- Activity Bars -->
<section class="g-pa-20 g-mb-10">
<!-- Advertising Income -->
<div class="g-mb-30">
<div class="media u-link-v5 g-color-white g-mb-10">
<span class="media-body align-self-center">Advertising Income</span>
<span class="d-flex align-self-center">
<svg class="g-fill-white-opacity-0_5" width="12px" height="20px" viewBox="0 0 12 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(-21.000000, -751.000000)">
<g transform="translate(0.000000, 64.000000)">
<g transform="translate(20.000000, 619.000000)">
<g transform="translate(1.000000, 68.000000)">
<polygon points="6 20 0 13.9709049 0.576828937 13.3911999 5.59205874 18.430615 5.59205874 0 6.40794126 0 6.40794126 18.430615 11.4223552 13.3911999 12 13.9709049"></polygon>
</g>
</g>
</g>
</g>
</svg>
<svg class="g-fill-lightblue-v3" width="12px" height="20px" viewBox="0 0 12 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(-33.000000, -751.000000)">
<g transform="translate(0.000000, 64.000000)">
<g transform="translate(20.000000, 619.000000)">
<g transform="translate(1.000000, 68.000000)">
<polygon transform="translate(18.000000, 10.000000) scale(1, -1) translate(-18.000000, -10.000000)" points="18 20 12 13.9709049 12.5768289 13.3911999 17.5920587 18.430615 17.5920587 0 18.4079413 0 18.4079413 18.430615 23.4223552 13.3911999 24 13.9709049"></polygon>
</g>
</g>
</g>
</g>
</svg>
</span>
</div>
<div class="progress g-height-4 g-bg-gray-light-v8 g-rounded-2">
<div class="progress-bar g-bg-teal-v2 g-rounded-2" role="progressbar" style="width: 70%" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<!-- End Advertising Income -->
<!-- Projects Income -->
<div class="g-mb-30">
<div class="media u-link-v5 g-color-white g-mb-10">
<span class="media-body align-self-center">Projects Income</span>
<span class="d-flex align-self-center">
<svg class="g-fill-red" width="12px" height="20px" viewBox="0 0 12 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(-21.000000, -751.000000)">
<g transform="translate(0.000000, 64.000000)">
<g transform="translate(20.000000, 619.000000)">
<g transform="translate(1.000000, 68.000000)">
<polygon points="6 20 0 13.9709049 0.576828937 13.3911999 5.59205874 18.430615 5.59205874 0 6.40794126 0 6.40794126 18.430615 11.4223552 13.3911999 12 13.9709049"></polygon>
</g>
</g>
</g>
</g>
</svg>
<svg class="g-fill-white-opacity-0_5" width="12px" height="20px" viewBox="0 0 12 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(-33.000000, -751.000000)">
<g transform="translate(0.000000, 64.000000)">
<g transform="translate(20.000000, 619.000000)">
<g transform="translate(1.000000, 68.000000)">
<polygon transform="translate(18.000000, 10.000000) scale(1, -1) translate(-18.000000, -10.000000)" points="18 20 12 13.9709049 12.5768289 13.3911999 17.5920587 18.430615 17.5920587 0 18.4079413 0 18.4079413 18.430615 23.4223552 13.3911999 24 13.9709049"></polygon>
</g>
</g>
</g>
</g>
</svg>
</span>
</div>
<div class="progress g-height-4 g-bg-gray-light-v8 g-rounded-2">
<div class="progress-bar g-bg-lightblue-v4 g-rounded-2" role="progressbar" style="width: 40%" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<!-- End Projects Income -->
<!-- Template Sales -->
<div>
<div class="media u-link-v5 g-color-white g-mb-10">
<span class="media-body align-self-center">Template Sales</span>
<span class="d-flex align-self-center">
<svg class="g-fill-white-opacity-0_5" width="12px" height="20px" viewBox="0 0 12 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(-21.000000, -751.000000)">
<g transform="translate(0.000000, 64.000000)">
<g transform="translate(20.000000, 619.000000)">
<g transform="translate(1.000000, 68.000000)">
<polygon points="6 20 0 13.9709049 0.576828937 13.3911999 5.59205874 18.430615 5.59205874 0 6.40794126 0 6.40794126 18.430615 11.4223552 13.3911999 12 13.9709049"></polygon>
</g>
</g>
</g>
</g>
</svg>
<svg class="g-fill-lightblue-v3" width="12px" height="20px" viewBox="0 0 12 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(-33.000000, -751.000000)">
<g transform="translate(0.000000, 64.000000)">
<g transform="translate(20.000000, 619.000000)">
<g transform="translate(1.000000, 68.000000)">
<polygon transform="translate(18.000000, 10.000000) scale(1, -1) translate(-18.000000, -10.000000)" points="18 20 12 13.9709049 12.5768289 13.3911999 17.5920587 18.430615 17.5920587 0 18.4079413 0 18.4079413 18.430615 23.4223552 13.3911999 24 13.9709049"></polygon>
</g>
</g>
</g>
</g>
</svg>
</span>
</div>
<div class="progress g-height-4 g-bg-gray-light-v8 g-rounded-2">
<div class="progress-bar g-bg-darkblue-v2 g-rounded-2" role="progressbar" style="width: 90%" aria-valuenow="90" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<!-- End Template Sales -->
</section>
<!-- End Activity Bars -->
<!-- Activity Accounts -->
<section class="g-pa-20">
<h5 class="text-uppercase g-font-size-default g-letter-spacing-0_5 g-mb-10">My accounts</h5>
<div class="media u-header-dropdown-bordered-v2 g-py-10">
<div class="d-flex align-self-center g-mr-12">
<span class="u-badge-v2--sm g-pos-stc g-transform-origin--top-left g-bg-teal-v2"></span>
</div>
<div class="media-body align-self-center">Credit Card</div>
<div class="d-flex text-right">$12.240</div>
</div>
<div class="media u-header-dropdown-bordered-v2 g-py-10">
<div class="d-flex align-self-center g-mr-12">
<span class="u-badge-v2--sm g-pos-stc g-transform-origin--top-left g-bg-lightblue-v4"></span>
</div>
<div class="media-body align-self-center">Debit Card</div>
<div class="d-flex text-right">$228.110</div>
</div>
<div class="media g-py-10">
<div class="d-flex align-self-center g-mr-12">
<span class="u-badge-v2--sm g-pos-stc g-transform-origin--top-left g-bg-darkblue-v2"></span>
</div>
<div class="media-body align-self-center">Savings Account</div>
<div class="d-flex text-right">$128.248.000</div>
</div>
</section>
<!-- End Activity Accounts -->
<!-- Activity Transactions -->
<section class="g-pa-20">
<h5 class="text-uppercase g-font-size-default g-letter-spacing-0_5 g-mb-10">Transactions</h5>
<!-- Transaction Item -->
<div class="u-header-dropdown-bordered-v2 g-py-20">
<div class="media g-pos-rel">
<div class="d-flex align-self-start g-pt-3 g-mr-12">
<i class="hs-admin-plus g-color-lightblue-v4"></i>
</div>
<div class="media-body align-self-start">
<strong class="d-block g-font-size-17 g-font-weight-400 g-line-height-1">$240.00</strong>
<p class="mb-0 g-mt-5">Addiction When Gambling Becomes</p>
</div>
<em class="d-flex align-items-center g-pos-abs g-top-0 g-right-0 g-font-style-normal g-color-lightblue-v2">
<i class="hs-admin-time icon-clock g-font-size-default g-mr-8"></i> <small>5 Min ago</small>
</em>
</div>
</div>
<!-- End Transaction Item -->
<!-- Transaction Item -->
<div class="u-header-dropdown-bordered-v2 g-py-20">
<div class="media g-pos-rel">
<div class="d-flex align-self-start g-pt-3 g-mr-12">
<i class="hs-admin-minus g-color-red"></i>
</div>
<div class="media-body align-self-start">
<strong class="d-block g-font-size-17 g-font-weight-400 g-line-height-1">$126.00</strong>
<p class="mb-0 g-mt-5">Make Myspace Your</p>
</div>
<em class="d-flex align-items-center g-pos-abs g-top-0 g-right-0 g-font-style-normal g-color-lightblue-v2">
<i class="hs-admin-time icon-clock g-font-size-default g-mr-8"></i> <small>25 Nov 2017</small>
</em>
</div>
</div>
<!-- End Transaction Item -->
<!-- Transaction Item -->
<div class="u-header-dropdown-bordered-v2 g-py-20">
<div class="media g-pos-rel">
<div class="d-flex align-self-start g-pt-3 g-mr-12">
<i class="hs-admin-plus g-color-lightblue-v4"></i>
</div>
<div class="media-body align-self-start">
<strong class="d-block g-font-size-17 g-font-weight-400 g-line-height-1">$560.00</strong>
<p class="mb-0 g-mt-5">Writing A Good Headline</p>
</div>
<em class="d-flex align-items-center g-pos-abs g-top-0 g-right-0 g-font-style-normal g-color-lightblue-v2">
<i class="hs-admin-time icon-clock g-font-size-default g-mr-8"></i> <small>22 Nov 2017</small>
</em>
</div>
</div>
<!-- End Transaction Item -->
<!-- Transaction Item -->
<div class="u-header-dropdown-bordered-v2 g-py-20">
<div class="media g-pos-rel">
<div class="d-flex align-self-start g-pt-3 g-mr-12">
<i class="hs-admin-plus g-color-lightblue-v4"></i>
</div>
<div class="media-body align-self-start">
<strong class="d-block g-font-size-17 g-font-weight-400 g-line-height-1">$6.00</strong>
<p class="mb-0 g-mt-5">Buying Used Electronic Equipment</p>
</div>
<em class="d-flex align-items-center g-pos-abs g-top-0 g-right-0 g-font-style-normal g-color-lightblue-v2">
<i class="hs-admin-time icon-clock g-font-size-default g-mr-8"></i> <small>13 Oct 2017</small>
</em>
</div>
</div>
<!-- End Transaction Item -->
<!-- Transaction Item -->
<div class="u-header-dropdown-bordered-v2 g-py-20">
<div class="media g-pos-rel">
<div class="d-flex align-self-start g-pt-3 g-mr-12">
<i class="hs-admin-plus g-color-lightblue-v4"></i>
</div>
<div class="media-body align-self-start">
<strong class="d-block g-font-size-17 g-font-weight-400 g-line-height-1">$320.00</strong>
<p class="mb-0 g-mt-5">Gambling Becomes A Problem</p>
</div>
<em class="d-flex align-items-center g-pos-abs g-top-0 g-right-0 g-font-style-normal g-color-lightblue-v2">
<i class="hs-admin-time icon-clock g-font-size-default g-mr-8"></i> <small>27 Jul 2017</small>
</em>
</div>
</div>
<!-- End Transaction Item -->
<!-- Transaction Item -->
<div class="u-header-dropdown-bordered-v2 g-py-20">
<div class="media g-pos-rel">
<div class="d-flex align-self-start g-pt-3 g-mr-12">
<i class="hs-admin-minus g-color-red"></i>
</div>
<div class="media-body align-self-start">
<strong class="d-block g-font-size-17 g-font-weight-400 g-line-height-1">$28.00</strong>
<p class="mb-0 g-mt-5">Baby Monitor Technology</p>
</div>
<em class="d-flex align-items-center g-pos-abs g-top-0 g-right-0 g-font-style-normal g-color-lightblue-v2">
<i class="hs-admin-time icon-clock g-font-size-default g-mr-8"></i> <small>05 Mar 2017</small>
</em>
</div>
</div>
<!-- End Transaction Item -->
<!-- Transaction Item -->
<div class="u-header-dropdown-bordered-v2 g-py-20">
<div class="media g-pos-rel">
<div class="d-flex align-self-start g-pt-3 g-mr-12">
<i class="hs-admin-plus g-color-lightblue-v4"></i>
</div>
<div class="media-body align-self-start">
<strong class="d-block g-font-size-17 g-font-weight-400 g-line-height-1">$490.00</strong>
<p class="mb-0 g-mt-5">Adwords Keyword Research For Beginners</p>
</div>
<em class="d-flex align-items-center g-pos-abs g-top-0 g-right-0 text-uppercase g-font-size-11 g-letter-spacing-0_5 g-font-style-normal g-color-lightblue-v2">
<i class="hs-admin-time icon-clock g-font-size-default g-mr-8"></i> 09 Feb 2017
</em>
</div>
</div>
<!-- End Transaction Item -->
<!-- Transaction Item -->
<div class="u-header-dropdown-bordered-v2 g-py-20">
<div class="media g-pos-rel">
<div class="d-flex align-self-start g-pt-3 g-mr-12">
<i class="hs-admin-minus g-color-red"></i>
</div>
<div class="media-body align-self-start">
<strong class="d-block g-font-size-17 g-font-weight-400 g-line-height-1">$14.20</strong>
<p class="mb-0 g-mt-5">A Good Autoresponder</p>
</div>
<em class="d-flex align-items-center g-pos-abs g-top-0 g-right-0 text-uppercase g-font-size-11 g-letter-spacing-0_5 g-font-style-normal g-color-lightblue-v2">
<i class="hs-admin-time icon-clock g-font-size-default g-mr-8"></i> 09 Feb 2017
</em>
</div>
</div>
<!-- End Transaction Item -->
</section>
<!-- End Activity Transactions -->
</div>
<!-- End Top Activity Panel -->
</div>
</header>
<!-- End Header -->
<main class="container-fluid px-0">
<div class="row no-gutters g-pos-rel g-overflow-x-hidden">
<!-- Sidebar Nav -->
<div id="sideNav" class="col-auto u-sidebar-navigation-v1 u-sidebar-navigation--dark">
<ul id="sideNavMenu" class="u-sidebar-navigation-v1-menu u-side-nav--top-level-menu g-min-height-100vh mb-0 g-pt-65">
<!-- Packages -->
<li class="u-sidebar-navigation-v1-menu-item u-side-nav--top-level-menu-item has-active">
<a class="media u-side-nav--top-level-menu-link u-side-nav--hide-on-hidden g-px-15 g-py-12" href="@(Url.Action("Index","NewVisitors"))">
<span class="d-flex align-self-center g-font-size-18 g-mr-18">
<i class="hs-admin-medall"></i>
</span>
<span class="media-body align-self-center">新朋友</span>
</a>
</li>
<!-- End Packages -->
<li class="u-sidebar-navigation-v1-menu-item u-side-nav--top-level-menu-item">
<a class="media u-side-nav--top-level-menu-link u-side-nav--hide-on-hidden g-px-15 g-py-12" href="#">
<span class="d-flex align-self-center g-font-size-18 g-mr-18">
<i class="hs-admin-user"></i>
</span>
<span class="media-body align-self-center">教友清單</span>
</a>
</li>
<li class="u-sidebar-navigation-v1-menu-item u-side-nav--top-level-menu-item">
<a class="media u-side-nav--top-level-menu-link u-side-nav--hide-on-hidden g-px-15 g-py-12" href="#">
<span class="d-flex align-self-center g-font-size-18 g-mr-18">
<i class="hs-admin-crown"></i>
</span>
<span class="media-body align-self-center">細胞小組管理</span>
</a>
</li>
<li class="u-sidebar-navigation-v1-menu-item u-side-nav--top-level-menu-item">
<a class="media u-side-nav--top-level-menu-link u-side-nav--hide-on-hidden g-px-15 g-py-12" href="#">
<span class="d-flex align-self-center g-font-size-18 g-mr-18">
<i class="hs-admin-announcement"></i>
</span>
<span class="media-body align-self-center">最新消息管理</span>
</a>
</li>
<li class="u-sidebar-navigation-v1-menu-item u-side-nav--top-level-menu-item">
<a class="media u-side-nav--top-level-menu-link u-side-nav--hide-on-hidden g-px-15 g-py-12" href="#">
<span class="d-flex align-self-center g-font-size-18 g-mr-18">
<i class="hs-admin-basketball"></i>
</span>
<span class="media-body align-self-center">活動管理</span>
</a>
</li>
<li class="u-sidebar-navigation-v1-menu-item u-side-nav--top-level-menu-item">
<a class="media u-side-nav--top-level-menu-link u-side-nav--hide-on-hidden g-px-15 g-py-12" href="#">
<span class="d-flex align-self-center g-font-size-18 g-mr-18">
<i class="hs-admin-blackboard"></i>
</span>
<span class="media-body align-self-center">主日信息發布</span>
</a>
</li>
</ul>
</div>
<!-- End Sidebar Nav -->
<div class="col g-ml-45 g-ml-0--lg g-pt-65">
<div class="g-bg-gray-light-v8 g-pa-20">
<ul class="u-list-inline g-color-gray-dark-v6">
<li class="list-inline-item g-mr-10">
<a class="u-link-v5 g-color-gray-dark-v6 g-color-lightblue-v3--hover g-valign-middle" href="#">Dashboard</a>
<i class="hs-admin-angle-right g-font-size-12 g-color-gray-light-v6 g-valign-middle g-ml-10"></i>
</li>
@if (!string.IsNullOrEmpty(ViewBag.returnUrl2))
{
<li class="list-inline-item g-mr-10">
<a class="u-link-v5 g-color-gray-dark-v6 g-color-lightblue-v3--hover g-valign-middle" href="@ViewBag.returnUrl2">@ViewBag.returnUrlTitle2</a>
<i class="hs-admin-angle-right g-font-size-12 g-color-gray-light-v6 g-valign-middle g-ml-10"></i>
</li>
}
@if (!string.IsNullOrEmpty(ViewBag.returnUrl))
{
<li class="list-inline-item g-mr-10">
<a class="u-link-v5 g-color-gray-dark-v6 g-color-lightblue-v3--hover g-valign-middle" href="@ViewBag.returnUrl">@ViewBag.returnUrlTitle</a>
<i class="hs-admin-angle-right g-font-size-12 g-color-gray-light-v6 g-valign-middle g-ml-10"></i>
</li>
}
<li class="list-inline-item">
<span class="g-valign-middle">@ViewBag.Title</span>
</li>
</ul>
</div>
@*<section class="g-color-white g-bg-gray-dark-v1 g-py-30" style="background-image: url(/images/bg/pattern3.png);">
<div class="container-fluid">
<div class="d-sm-flex text-center">
<div class="align-self-center">
<h2 class="h3 g-font-weight-300 w-100 g-mb-10 g-mb-0--md">@ViewBag.title</h2>
</div>
@*<div class="align-self-center ml-auto">
<ul class="u-list-inline">
<li class="list-inline-item g-mr-5">
<a class="u-link-v5 g-color-white g-color-primary--hover" href="#!">Home</a>
<i class="g-color-gray-light-v2 g-ml-5">/</i>
</li>
<li class="list-inline-item g-mr-5">
<a class="u-link-v5 g-color-white g-color-primary--hover" href="#!">Pages</a>
<i class="g-color-gray-light-v2 g-ml-5">/</i>
</li>
<li class="list-inline-item g-color-primary">
<span>About Us</span>
</li>
</ul>
</div>
</div>
</div>
</section>*@
<div class="g-pt-20 g-overflow-y-auto g-pt-20" style="height: calc(100vh - 225px);">
@RenderBody()
</div>
<!-- Footer -->
<footer id="footer" class="u-footer--bottom-sticky g-bg-white g-color-gray-dark-v6 g-brd-top g-brd-gray-light-v7 g-pa-20">
<div class="row align-items-center">
<!-- Footer Nav -->
<div class="col-md-4 g-mb-10 g-mb-0--md">
<ul class="list-inline text-center text-md-left mb-0">
<li class="list-inline-item">
<a class="g-color-gray-dark-v6 g-color-lightblue-v3--hover" href="#!">FAQ</a>
</li>
<li class="list-inline-item">
<span class="g-color-gray-dark-v6">|</span>
</li>
<li class="list-inline-item">
<a class="g-color-gray-dark-v6 g-color-lightblue-v3--hover" href="#!">Support</a>
</li>
<li class="list-inline-item">
<span class="g-color-gray-dark-v6">|</span>
</li>
<li class="list-inline-item">
<a class="g-color-gray-dark-v6 g-color-lightblue-v3--hover" href="#!">Contact Us</a>
</li>
</ul>
</div>
<!-- End Footer Nav -->
<!-- Footer Socials -->
<div class="col-md-4 g-mb-10 g-mb-0--md">
<ul class="list-inline g-font-size-16 text-center mb-0">
<li class="list-inline-item g-mx-10">
<a href="#!" class="g-color-facebook g-color-lightblue-v3--hover">
<i class="fa fa-facebook-square"></i>
</a>
</li>
<li class="list-inline-item g-mx-10">
<a href="#!" class="g-color-google-plus g-color-lightblue-v3--hover">
<i class="fa fa-google-plus"></i>
</a>
</li>
<li class="list-inline-item g-mx-10">
<a href="#!" class="g-color-black g-color-lightblue-v3--hover">
<i class="fa fa-github"></i>
</a>
</li>
<li class="list-inline-item g-mx-10">
<a href="#!" class="g-color-twitter g-color-lightblue-v3--hover">
<i class="fa fa-twitter"></i>
</a>
</li>
</ul>
</div>
<!-- End Footer Socials -->
<!-- Footer Copyrights -->
<div class="col-md-4 text-center text-md-right">
<small class="d-block g-font-size-default">&copy; 2018 Htmlstream. All Rights Reserved.</small>
</div>
<!-- End Footer Copyrights -->
</div>
</footer>
<!-- End Footer -->
</div>
</div>
</main>
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/common")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/Dashboard")
<!-- JS Plugins Init. -->
<script>
$(function (parameters) {
// initialization of custom select
$('.js-select').selectpicker();
// initialization of hamburger
$.HSCore.helpers.HSHamburgers.init('.hamburger');
// initialization of charts
$.HSCore.components.HSAreaChart.init('.js-area-chart');
$.HSCore.components.HSDonutChart.init('.js-donut-chart');
$.HSCore.components.HSBarChart.init('.js-bar-chart');
// initialization of sidebar navigation component
$.HSCore.components.HSSideNav.init('.js-side-nav', {
afterOpen: function () {
setTimeout(function () {
$.HSCore.components.HSAreaChart.init('.js-area-chart');
$.HSCore.components.HSDonutChart.init('.js-donut-chart');
$.HSCore.components.HSBarChart.init('.js-bar-chart');
}, 400);
},
afterClose: function () {
setTimeout(function () {
$.HSCore.components.HSAreaChart.init('.js-area-chart');
$.HSCore.components.HSDonutChart.init('.js-donut-chart');
$.HSCore.components.HSBarChart.init('.js-bar-chart');
}, 400);
}
});
// initialization of range datepicker
$.HSCore.components.HSRangeDatepicker.init('#rangeDatepicker, #rangeDatepicker2, #rangeDatepicker3');
// initialization of datepicker
$.HSCore.components.HSDatepicker.init('#datepicker', {
dayNamesMin: [
'SU',
'MO',
'TU',
'WE',
'TH',
'FR',
'SA'
]
});
// initialization of HSDropdown component
$.HSCore.components.HSDropdown.init($('[data-dropdown-target]'), { dropdownHideOnScroll: false });
// initialization of custom scrollbar
$.HSCore.components.HSScrollBar.init($('.js-custom-scroll'));
// initialization of popups
$.HSCore.components.HSPopup.init('.js-fancybox', {
btnTpl: {
smallBtn: '<button data-fancybox-close class="btn g-pos-abs g-top-25 g-right-30 g-line-height-1 g-bg-transparent g-font-size-16 g-color-gray-light-v3 g-brd-none p-0" title=""><i class="hs-admin-close"></i></button>'
}
});
});
function Speak(word) {
var msg = new SpeechSynthesisUtterance(word);
window.speechSynthesis.speak(msg);
}
</script>
@RenderSection("scripts", required: false)
</body>
</html>

View File

@ -1,110 +0,0 @@
@model Church.Net.Entity.Vocabulary
<style>
.vocalInput {
border: none;
width: 10.5ch;
background: repeating-linear-gradient(90deg, dimgrey 0, dimgrey 1ch, transparent 0, transparent 1.5ch) 0 100%/100% 2px no-repeat;
color: dimgrey;
font: 5ch consolas, monospace;
letter-spacing: .5ch;
}
.vocalInput:focus {
outline: none;
color: dodgerblue;
}
</style>
<div id="divSpellingPractice" class="jumbotron m-auto text-center">
<span class="mb-1 badge badge-info">
@Model.PartOfSpeech.ToString()
</span>
<h1 class="display-3" id="MarskedAnswer">
@Model.MaskedWord
<button class="btn btn-success p-4" onclick="Speak('@Html.Raw(Model.Word)')"><i class="g-absolute-centered g-font-size-20 hs-admin-announcement"></i></button>
@if (Model.PartOfSpeech == Church.Net.Entity.Enumeration.PartsOfSpeech.VerbsUnRegular)
{
@Html.Raw("<br>" + Model.MaskedVerbPast + " ; " + Model.MaskedVerbParticiple)
}
</h1>
<p><img id="volImg" class="img-fluid img-thumbnail g-max-width-380" src="@Model.ImagesUrl" /></p>
<p class="lead" id="definition">
@Model.DefinitionEn
</p>
<hr class="my-4">
<div class="progress mb-2">
<div id="spellProgress" class="progress-bar progress-bar-striped progress-bar-animated bg-success" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div>
</div>
<input class="vocalInput" id="txSpell" onkeyup="checkAnswer(this.value)" style="width:@Html.Raw(Model.Word.Length*1.5)px" />
<br />
<br />
<p class="lead">
<button class="btn btn-primary btn-lg" role="button" onclick="ShowTheAnswer()">Check the answer</button>
</p>
</div>
<script>
var spellingAnswer, lenOfAnswer;
var successCount, successReq;
var nextBtnId;
function SetUpSpellingQuitze(answer, showingId) {
spellingAnswer = answer;
lenOfAnswer = answer.length;
nextBtnId = showingId;
successReq = @Model.PracticeTimes;
$("#txSpell").width(lenOfAnswer * 1.5 + 'ch');
successCount = 0
$("#spellProgress").width((successCount / successReq * 100) + "%");
$("#spellProgress").html(successCount + ' / ' + successReq);
$("#txSpell").focus();
}
function ShowTheAnswer() {
//al('@Model.Word');
Swal.fire({
title: '@Model.Word',
text:'@Html.Raw(Model.DefinitionCh.Replace(Environment.NewLine,""))',
imageUrl: '@Model.ImagesUrl',
imageHeight: 200,
imageAlt: 'Answer'
})
}
function checkAnswer(value) {
if (value.length == lenOfAnswer) {
if (value.toLowerCase() == spellingAnswer.toLowerCase()) {
successCount = successCount + 1;
} else {
successCount = 0;
}
$("#txSpell").val("");
if (successCount >= successReq) {
if (nextBtnId == 'divNextQuiz') {
$("#" + nextBtnId).show("divNextQuiz");
} else {
swal("Good job!", "", "success").then(function () {
window.location.href = nextBtnId;
});
}
//
}
}
$("#spellProgress").width((successCount / successReq * 100) + "%");
$("#spellProgress").html(successCount+' / '+successReq);
}
@*$(function () {
SetUpSpellingQuitze('@Model.Word', 5, "divNextQuiz");
})*@
</script>

View File

@ -1,93 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
ViewBag.title = "Apply";
}
<div class="g-bg-img-hero g-bg-pos-top-center g-pos-rel g-z-index-1 g-mt-minus-100" style="background-image: url(/Images/svg/svg-bg5.svg);">
<div class="container g-pt-150 g-pb-30">
<div class="row center">
@Html.Partial("~/Areas/English/Views/Shared/_SpellPractice.cshtml", Model)
</div>
@using (Html.BeginForm("ApplyNext"))
{
<div class="form-group" id="divNextQuiz" style="display:none">
<div class="row">
<iframe id="frameDictionary" src="" class="g-width-100vw" style="height:500px;display:none"></iframe>
<div class="col-md-2 g-mb-20--md">
<button type="button" class="btn u-btn-outline-primary" onclick="QueryWord()">Query</button>
<button type="button" class="btn u-btn-outline-primary" onclick="QueryWord2()">Query</button>
</div>
</div>
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.DefinitionEn, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.HiddenFor(model=>model.Id)
@Html.EditorFor(model => model.PracticeSentence, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30", @multiLine = "true" } })
</div>
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Next" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
@section scripts{
<script>
$(function(){
SetUpSpellingQuitze('@Model.Word','divNextQuiz');
})
function QueryWord() {
if ($("#Word").val() != '') {
$('#frameDictionary').show('fast');
$('#frameDictionary').attr('src', 'https://dictionary.cambridge.org/us/dictionary/english-chinese-traditional/@Model.Word');
$("#DefinitionEn").focus();
$([document.documentElement, document.body]).animate({
scrollTop: $("#frameDictionary").offset().top
}, 1000);
}
}
function QueryWord2() {
if ($("#Word").val() != '') {
$('#frameDictionary').show('fast');
$('#frameDictionary').attr('src', 'https://dict.cn/@Model.Word');
$("#DefinitionEn").focus();
$([document.documentElement, document.body]).animate({
scrollTop: $("#frameDictionary").offset().top
}, 1000);
}
}
</script>
}

View File

@ -1,187 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
ViewBag.title="Select Word";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="g-bg-img-hero g-bg-pos-top-center g-pos-rel g-z-index-1 g-mt-minus-100" style="background-image: url(/Images/svg/svg-bg5.svg);">
<div class="container g-pt-150 g-pb-30">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PartOfSpeech, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EnumDropDownListFor(model => model.PartOfSpeech, htmlAttributes: new { @class = "w-100 u-select-v2 u-shadow-v19 g-brd-none g-color-black g-color-primary--hover g-bg-white text-left g-rounded-30 g-pl-30 g-py-12", @onchange = "PartOfSpeechChanged(value)" })
@Html.ValidationMessageFor(model => model.PartOfSpeech, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
</div>
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.Word, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.Word, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.Word, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
<div class="col-md-2 g-mb-20--md">
<button type="button" class="btn u-btn-outline-primary" onclick="QueryWord()">Query</button>
<button type="button" class="btn u-btn-outline-primary" onclick="QueryWord2()">Query</button>
</div>
<div class="col-md-4 g-mb-20--md nounPlural">
@Html.LabelFor(model => model.NounPlural, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.NounPlural, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.NounPlural, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
</div>
<div class="row verbForm" style="display:none">
<div class="col-md-4 g-mb-20--md ">
@Html.LabelFor(model => model.VerbPast, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.VerbPast, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.VerbPast, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
<div class="col-md-4 g-mb-20--md ">
@Html.LabelFor(model => model.VerbParticiple, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.VerbParticiple, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.VerbParticiple, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
</div>
<div class="row">
<iframe id="frameDictionary" src="" class="g-width-100vw" style="height:500px;display:none"></iframe>
</div>
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.DefinitionEn, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.DefinitionEn, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30", @multiLine = "true" } })
@Html.ValidationMessageFor(model => model.DefinitionEn, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.DefinitionCh, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.DefinitionCh, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.DefinitionCh, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
</div>
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.ImagesUrl, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.ImagesUrl, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.ImagesUrl, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
<div class="col-md-6 g-mb-20--md">
<button type="button" class="btn btn-primary" onclick="QueryImage()">Query</button>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
}
@section scripts{
<script>
function PartOfSpeechChanged(value) {
if (value == "2") {
$('.verbForm').show('slow')
} else {
$('.verbForm').hide('slow')
}
if (value == "0") {
$('.nounPlural').show('slow')
} else {
$('.nounPlural').hide('slow')
}
}
function QueryWord() {
if ($("#Word").val() != '') {
$('#frameDictionary').show('fast');
$('#frameDictionary').attr('src', 'https://dictionary.cambridge.org/us/dictionary/english-chinese-traditional/' + $("#Word").val());
$("#DefinitionEn").focus();
$([document.documentElement, document.body]).animate({
scrollTop: $("#frameDictionary").offset().top
}, 1000);
}
}
function QueryWord2() {
if ($("#Word").val() != '') {
$('#frameDictionary').show('fast');
$('#frameDictionary').attr('src', 'https://dict.cn/' + $("#Word").val());
$("#DefinitionEn").focus();
$([document.documentElement, document.body]).animate({
scrollTop: $("#frameDictionary").offset().top
}, 1000);
}
}
function QueryImage() {
if ($("#Word").val() !='') {
var win = window.open("https://www.google.com/search?q=" + $("#Word").val() + "&hl=en&tbm=isch&source=lnt&sa=X&ved=0ahUKEwiQyc-w1NrjAhWRKn0KHYGgDf8QpwUIIw&biw=1368&bih=770&dpr=2", '_blank');
if (win) {
//Browser has allowed it to be opened
$("#ImageUrl").focus()
win.focus();
} else {
//Browser has blocked it
alert('Please allow popups for this website');
}
}
}
</script>
}

View File

@ -1,149 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Delete</title>
</head>
<body>
<div class="text-center g-mb-50--md">
<h2 class="h4 g-mb-0">
Are you sure you want to <span class="g-color-primary g-ml-5">DELETE</span> this?
</h2>
</div>
<div class="g-bg-img-hero g-bg-pos-top-center g-pos-rel g-z-index-1 g-mt-minus-100" style="background-image: url(/Images/svg/svg-bg5.svg);">
<div class="container g-pt-150 g-pb-30">
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.Word, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.Word)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.NounPlural, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.NounPlural)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.VerbPast, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.VerbPast)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.VerbParticiple, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.VerbParticiple)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PartOfSpeech, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PartOfSpeech)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.ImagesUrl, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.ImagesUrl)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeDate, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeDate)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeSelect, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeSelect)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeMemorized, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeMemorized)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeVisualize, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeVisualize)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeApply, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeApply)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeReview, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeReview)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeSentence, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeSentence)
</label>
</div>
</div>
<div class="row">
<div class="col-sm-6 g-mt-30 g-mb-30">
@using (Html.BeginForm())
{
<div class="d-flex">
@Html.AntiForgeryToken()
<a class="btn btn-block u-shadow-v32 g-brd-black g-brd-2 g-color-black g-color-white--hover g-bg-transparent g-bg-black--hover g-font-size-16 g-rounded-30 g-py-10 mr-2 g-mt-0" href="@Url.Action("Index")">Back to List</a>
<button class="btn btn-block u-shadow-v32 g-brd-none g-color-white g-bg-black g-bg-primary--hover g-font-size-16 g-rounded-30 g-py-10 ml-2 g-mt-0" type="submit">Delete</button>
</div>
}
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,138 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Details</title>
</head>
<body>
<div class="text-center g-mb-50--md">
<h2 class="h4 g-mb-0">
Detail of <span class="g-color-primary g-ml-5">Details</span>
</h2>
</div>
<div class="g-bg-img-hero g-bg-pos-top-center g-pos-rel g-z-index-1 g-mt-minus-100" style="background-image: url(/Images/svg/svg-bg5.svg);">
<div class="container g-pt-150 g-pb-30">
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.Word, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.Word)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.NounPlural, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.NounPlural)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.VerbPast, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.VerbPast)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.VerbParticiple, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.VerbParticiple)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PartOfSpeech, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PartOfSpeech)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.ImagesUrl, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.ImagesUrl)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeDate, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeDate)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeSelect, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeSelect)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeMemorized, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeMemorized)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeVisualize, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeVisualize)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeApply, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeApply)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeReview, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeReview)
</label>
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PracticeSentence, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
<label class="d-block g-font-size-20 g-pl-30">
@Html.DisplayFor(model => model.PracticeSentence)
</label>
</div>
</div>
<div class="row">
<div class="col-sm-6 g-mt-30 g-mb-30">
@using (Html.BeginForm())
{
<div class="d-flex">
@Html.AntiForgeryToken()
<a class="btn btn-block u-shadow-v32 g-brd-black g-brd-2 g-color-black g-color-white--hover g-bg-transparent g-bg-black--hover g-font-size-16 g-rounded-30 g-py-10 mr-2 g-mt-0" href="@Url.Action("Index")">Back to List</a>
<a class="btn btn-block u-shadow-v32 g-brd-none g-color-white g-bg-black g-bg-primary--hover g-font-size-16 g-rounded-30 g-py-10 ml-2 g-mt-0" href="@Url.Action("Edit", new { id = Model.Id })">Edit</button>
</div>
}
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,180 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
ViewBag.title = "Edit Word";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="g-bg-img-hero g-bg-pos-top-center g-pos-rel g-z-index-1 g-mt-minus-100" style="background-image: url(/Images/svg/svg-bg5.svg);">
<div class="container g-pt-150 g-pb-30">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.PracticeDate)
@Html.HiddenFor(model => model.PracticeStage)
@Html.HiddenFor(model => model.FlashCardTimes)
@Html.HiddenFor(model => model.InsertDate)
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.PartOfSpeech, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EnumDropDownListFor(model => model.PartOfSpeech, htmlAttributes: new { @class = "w-100 u-select-v2 u-shadow-v19 g-brd-none g-color-black g-color-primary--hover g-bg-white text-left g-rounded-30 g-pl-30 g-py-12", @onchange = "PartOfSpeechChanged(value)" })
@Html.ValidationMessageFor(model => model.PartOfSpeech, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
</div>
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.Word, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.Word, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.Word, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
<div class="col-md-2 g-mb-20--md">
<button type="button" class="btn u-btn-outline-primary" onclick="QueryWord()">Query</button>
</div>
<div class="col-md-4 g-mb-20--md nounPlural">
@Html.LabelFor(model => model.NounPlural, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.NounPlural, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.NounPlural, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
</div>
<div class="row verbForm" style="display:none">
<div class="col-md-4 g-mb-20--md ">
@Html.LabelFor(model => model.VerbPast, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.VerbPast, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.VerbPast, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
<div class="col-md-4 g-mb-20--md ">
@Html.LabelFor(model => model.VerbParticiple, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.VerbParticiple, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.VerbParticiple, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
</div>
<div class="row">
<iframe id="frameDictionary" src="" class="g-width-100vw" style="height:500px;display:none"></iframe>
</div>
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.DefinitionEn, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.DefinitionEn, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30", @multiLine = "true" } })
@Html.ValidationMessageFor(model => model.DefinitionEn, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.DefinitionCh, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.DefinitionCh, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.DefinitionCh, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
</div>
<div class="row">
<div class="col-md-6 g-mb-20--md">
@Html.LabelFor(model => model.ImagesUrl, htmlAttributes: new { @class = "g-font-weight-500 g-font-size-15 g-pl-30" })
@Html.EditorFor(model => model.ImagesUrl, new { htmlAttributes = new { @class = "form-control u-shadow-v19 g-brd-none g-bg-white g-font-size-16 g-rounded-30 g-px-30 g-py-13 g-mb-30" } })
@Html.ValidationMessageFor(model => model.ImagesUrl, "", new { @class = "form-control-feedback d-block g-bg-red g-color-white g-font-size-12 g-px-14 mt-0" })
</div>
<div class="col-md-6 g-mb-20--md">
<img class="img-thumbnail g-max-width-200" src="@Model.ImagesUrl" />
<button type="button" class="btn btn-primary" onclick="QueryImage()">Query</button>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
}
@section scripts{
<script>
function PartOfSpeechChanged(value) {
if (value == "2") {
$('.verbForm').show('slow')
} else {
$('.verbForm').hide('slow')
}
if (value == "0") {
$('.nounPlural').show('slow')
} else {
$('.nounPlural').hide('slow')
}
}
function QueryWord() {
if ($("#Word").val() != '') {
$('#frameDictionary').show('fast');
$('#frameDictionary').attr('src', 'https://dictionary.cambridge.org/us/dictionary/english-chinese-traditional/' + $("#Word").val());
$("#DefinitionEn").focus();
$([document.documentElement, document.body]).animate({
scrollTop: $("#frameDictionary").offset().top
}, 1000);
}
}
function QueryImage() {
if ($("#Word").val() !='') {
var win = window.open("https://www.google.com/search?q=" + $("#Word").val() + "&hl=en&tbm=isch&source=lnt&sa=X&ved=0ahUKEwiQyc-w1NrjAhWRKn0KHYGgDf8QpwUIIw&biw=1368&bih=770&dpr=2", '_blank');
if (win) {
//Browser has allowed it to be opened
$("#ImageUrl").focus()
win.focus();
} else {
//Browser has blocked it
alert('Please allow popups for this website');
}
}
}
</script>
}

View File

@ -1,64 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
ViewBag.Title = "FlashCard";
}
@using (Html.BeginForm("FlashCardNext"))
{
}
<div id="divSpellingPractice" class="jumbotron m-auto text-center">
<span class="mb-1 badge badge-info">
@Model.PartOfSpeech.ToString()
</span>
<h1 class="display-3" id="MarskedAnswer">
@Model.Word
<button class="btn btn-success p-4" onclick="Speak('@Html.Raw(Model.Word)')"><i class="g-absolute-centered g-font-size-20 hs-admin-announcement"></i></button>
@if (Model.PartOfSpeech == Church.Net.Entity.Enumeration.PartsOfSpeech.VerbsUnRegular)
{
@Html.Raw("<br>" + Model.MaskedVerbPast + " ; " + Model.MaskedVerbParticiple)
}
</h1>
<p><img id="volImg" class="img-fluid img-thumbnail g-max-width-380" src="@Model.ImagesUrl" /></p>
<p class="lead" id="definition">
@Model.DefinitionEn
</p>
<hr class="my-4">
<div class="progress mb-2">
<div id="spellProgress" class="progress-bar progress-bar-striped progress-bar-animated bg-success" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div>
</div>
<input class="vocalInput" id="txSpell" onkeyup="checkAnswer(this.value)" style="width:@Html.Raw(Model.Word.Length*1.5)px" />
<br />
<br />
<p class="lead">
<button class="btn btn-primary btn-lg" role="button" onclick="ShowTheAnswer()">Check the answer</button>
</p>
</div>
<div class="form-group" id="divNextQuiz" >
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Next" class="btn btn-default" onclick="location.href='@Url.Action("FlashCardNext", "Vocabularies",new { id=Model.Id})'" />
@*<input type="submit" value="Next" class="btn btn-default" />*@
<input type="button" value="Forgot this word" class="btn btn-danger" onclick="location.href='@Url.Action("FlashCardForgot", "Vocabularies",new { id=Model.Id})'" />
</div>
</div>
<script>
function ShowTheAnswer() {
//al('@Model.Word');
Swal.fire({
title: '@Model.Word',
text:'@Html.Raw(Model.DefinitionCh.Replace(Environment.NewLine,""))',
imageUrl: '@Model.ImagesUrl',
imageHeight: 200,
imageAlt: 'Answer'
})
}
</script>

View File

@ -1,168 +0,0 @@
@model IEnumerable<Church.Net.Entity.Vocabulary>
<div class="g-px-20">
<div class="media">
<div class="d-flex align-self-center">
<h1 class="g-font-weight-300 g-font-size-28 g-color-black mb-0">@ViewBag.Title</h1>
</div>
</div>
<hr class="d-flex g-brd-gray-light-v7 g-my-30">
<div class="media flex-wrap g-mb-30">
<div class="d-flex align-self-center align-items-center">
<span class="g-hidden-sm-down g-color-gray-dark-v6 g-mr-12">Type:</span>
<div class="u-select--v1 g-pr-20">
<select class="js-select u-select--v1-select w-100" style="display: none;">
<option data-content='<span class="d-flex align-items-center"><span class="u-badge-v2--md g-pos-stc g-transform-origin--top-left g-bg-lightblue-v3 g-mr-8--sm"></span><span class="g-hidden-sm-down g-line-height-1_2 g-color-black">Friends</span></span>'>Friends</option>
<option data-content='<span class="d-flex align-items-center"><span class="u-badge-v2--md g-pos-stc g-transform-origin--top-left g-bg-teal-v2 g-mr-8--sm"></span><span class="g-hidden-sm-down g-line-height-1_2 g-color-black">Colleagues</span></span>'>Colleagues</option>
</select>
<i class="hs-admin-angle-down g-absolute-centered--y g-right-0 g-color-gray-light-v6 ml-auto"></i>
</div>
</div>
<div class="d-flex align-self-center align-items-center g-ml-10 g-ml-20--md g-ml-40--lg">
<span class="g-hidden-sm-down g-color-gray-dark-v6 g-mr-12">Position:</span>
<div class="u-select--v1 g-pr-20">
<select class="js-select u-select--v1-select w-100" style="display: none;">
<option data-content='<span class="d-flex align-items-center"><span class="g-line-height-1_2 g-color-black">All Positions</span></span>'>All Positions</option>
<option data-content='<span class="d-flex align-items-center"><span class="g-line-height-1_2 g-color-black">Manager</span></span>'>Manager</option>
<option data-content='<span class="d-flex align-items-center"><span class="g-line-height-1_2 g-color-black">Designer</span></span>'>Designer</option>
<option data-content='<span class="d-flex align-items-center"><span class="g-line-height-1_2 g-color-black">Developer</span></span>'>Developer</option>
</select>
<i class="hs-admin-angle-down g-absolute-centered--y g-right-0 g-color-gray-light-v6 ml-auto"></i>
</div>
</div>
<div class="d-flex g-hidden-md-up w-100"></div>
<div class="media-body align-self-center g-mt-10 g-mt-0--md">
<div class="input-group g-pos-rel g-max-width-380 float-right">
<input class="form-control g-font-size-default g-brd-gray-light-v7 g-brd-lightblue-v3--focus g-rounded-20 g-pl-20 g-pr-50 g-py-10" type="text" placeholder="Search for name, position">
<button class="btn g-pos-abs g-top-0 g-right-0 g-z-index-2 g-width-60 h-100 g-bg-transparent g-font-size-16 g-color-lightred-v2 g-color-lightblue-v3--hover rounded-0" type="submit">
<i class="hs-admin-search g-absolute-centered"></i>
</button>
</div>
</div>
</div>
<table class="table w-100 g-mb-25">
<thead class="g-hidden-sm-down g-color-gray-dark-v6">
<tr>
<th class="g-bg-gray-light-v8 g-font-weight-400 g-valign-middle g-brd-bottom-none g-py-15">
<div class="d-flex align-items-center justify-content-between">
@Html.DisplayNameFor(model => model.PracticeDate)
<!-- <a class="u-link-v5 g-line-height-1 g-color-gray-dark-v7 g-color-lightblue-v4--hover" href="#!">
<i class="hs-admin-arrows-vertical g-font-size-15"></i>
</a> -->
</div>
</th>
<th class="g-bg-gray-light-v8 g-font-weight-900 g-valign-middle g-brd-bottom-none g-py-15">
<div class="d-flex align-items-center justify-content-between">
@Html.DisplayNameFor(model => model.Word)
<!-- <a class="u-link-v5 g-line-height-1 g-color-gray-dark-v7 g-color-lightblue-v4--hover" href="#!">
<i class="hs-admin-arrows-vertical g-font-size-15"></i>
</a> -->
</div>
</th>
<th class="g-bg-gray-light-v8 g-font-weight-400 g-valign-middle g-brd-bottom-none g-py-15">
<div class="d-flex align-items-center justify-content-between">
@Html.DisplayNameFor(model => model.ImagesUrl)
<!-- <a class="u-link-v5 g-line-height-1 g-color-gray-dark-v7 g-color-lightblue-v4--hover" href="#!">
<i class="hs-admin-arrows-vertical g-font-size-15"></i>
</a> -->
</div>
</th>
<th class="g-bg-gray-light-v8 g-font-weight-400 g-valign-middle g-brd-bottom-none g-py-15 g-pr-25">
<div class="d-flex align-items-center justify-content-between">
Definition
</div>
</th>
<th class="g-bg-gray-light-v8 g-font-weight-400 g-valign-middle g-brd-bottom-none g-py-15 g-pr-25"></th>
</tr>
</thead>
<tbody class="g-font-size-default g-color-black" id="accordion-09" role="tablist" aria-multiselectable="true">
@foreach (var item in Model)
{
<tr>
<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
@Html.DisplayFor(modelItem => item.PracticeDate)
<br />
<span class="badge badge-info">@item.PracticeStage.ToString()</span>
@*<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
@Html.DisplayFor(modelItem => item.PracticeSelect)
</td>
<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
@Html.DisplayFor(modelItem => item.PracticeMemorized)
</td>
<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
@Html.DisplayFor(modelItem => item.PracticeVisualize)
</td>
<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
@Html.DisplayFor(modelItem => item.PracticeApply)
</td>
<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
@Html.DisplayFor(modelItem => item.PracticeReview)
</td>*@
</td>
<td class="g-valign-middle g-brd-top-none g-font-weight-900 g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
<span class="badge badge-info">@Html.DisplayFor(modelItem => item.PartOfSpeech)</span>
<h3>@Html.DisplayFor(modelItem => item.Word)</h3>
@if (item.PartOfSpeech == Church.Net.Entity.Enumeration.PartsOfSpeech.Nouns)
{
@Html.DisplayFor(modelItem => item.NounPlural)
}
else if (item.PartOfSpeech == Church.Net.Entity.Enumeration.PartsOfSpeech.VerbsUnRegular)
{
@Html.Raw(item.VerbPast);@Html.Raw(item.VerbParticiple)
}
<button class="btn btn-success p-4" onclick="Speak('@Html.Raw(item.Word)')"><i class="g-absolute-centered g-font-size-20 hs-admin-announcement"></i></button>
</td>
<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
<img class="img-thumbnail g-max-width-380" src="@item.ImagesUrl" />
</td>
<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm">
@Html.Raw(item.DefinitionEn)
<hr />
@Html.Raw(item.DefinitionCh)
</td>
<td class="g-valign-middle g-brd-top-none g-brd-bottom g-brd-gray-light-v7 g-py-15 g-py-30--md g-px-5 g-px-10--sm g-pr-25">
<div class="d-flex align-items-center g-line-height-1">
<a href="@Url.Action("Edit", new { id=item.Id })" class="u-link-v5 g-color-gray-light-v6 g-color-lightblue-v4--hover g-mr-15">
<i class="hs-admin-pencil g-font-size-18"></i>
</a>
<a href="@Url.Action("Delete", new { id=item.Id })" class="u-link-v5 g-color-gray-light-v6 g-color-lightblue-v4--hover">
<i class="hs-admin-trash g-font-size-18"></i>
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>

View File

@ -1,44 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
ViewBag.title = "Memorized";
}
<div class="g-bg-img-hero g-bg-pos-top-center g-pos-rel g-z-index-1 g-mt-minus-100" style="background-image: url(/Images/svg/svg-bg5.svg);">
<div class="container g-pt-150 g-pb-30">
<div class="row center">
@Html.Partial("~/Areas/English/Views/Shared/_SpellPractice.cshtml", Model)
</div>
<div class="form-group" id="divNextQuiz" style="display:none">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Next" class="btn btn-default" onclick="location.href='@Url.Action("MemorizedNext", "Vocabularies",new { id=Model.Id})'" />
@*<input type="submit" value="Next" class="btn btn-default" />*@
</div>
</div>
</div>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
@section scripts{
<script>
$(function(){
SetUpSpellingQuitze('@Model.Word','@Url.Action("MemorizedNext", "Vocabularies", new { id = Model.Id })');
})
</script>
}

View File

@ -1,47 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
ViewBag.title = "Review";
}
<div class="g-bg-img-hero g-bg-pos-top-center g-pos-rel g-z-index-1 g-mt-minus-100" style="background-image: url(/Images/svg/svg-bg5.svg);">
<div class="container g-pt-150 g-pb-30">
<div class="row center">
@Html.Partial("~/Areas/English/Views/Shared/_SpellPractice.cshtml", Model)
</div>
<div class="form-group" id="divNextQuiz" style="display:none">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Next" class="btn btn-success" onclick="location.href='@Url.Action("ReviewNext", "Vocabularies",new { id=Model.Id})'" />
<input type="button" value="Practice Again" class="btn btn-danger" onclick="location.href='@Url.Action("ReviewRepracticeNext", "Vocabularies",new { id=Model.Id})'" />
@*<input type="submit" value="Next" class="btn btn-default" />*@
</div>
</div>
</div>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
@section scripts{
<script>
$(function(){
SetUpSpellingQuitze('@Model.Word','divNextQuiz');
})
</script>
}

View File

@ -1,44 +0,0 @@
@model Church.Net.Entity.Vocabulary
@{
ViewBag.title = "Visualize";
}
<div class="g-bg-img-hero g-bg-pos-top-center g-pos-rel g-z-index-1 g-mt-minus-100" style="background-image: url(/Images/svg/svg-bg5.svg);">
<div class="container g-pt-150 g-pb-30">
<div class="row center">
@Html.Partial("~/Areas/English/Views/Shared/_SpellPractice.cshtml", Model)
</div>
<div class="form-group" id="divNextQuiz" style="display:none">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Next" class="btn btn-default" onclick="location.href='@Url.Action("VisualizeNext", "Vocabularies",new { id=Model.Id})'" />
@*<input type="submit" value="Next" class="btn btn-default" />*@
</div>
</div>
</div>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
@section scripts{
<script>
$(function(){
SetUpSpellingQuitze('@Model.Word','@Url.Action("VisualizeNext", "Vocabularies", new { id = Model.Id })');
})
</script>
}

View File

@ -1,3 +0,0 @@
@{
Layout = "~/Areas/English/Views/Shared/_Layout.cshtml";
}

View File

@ -1,36 +0,0 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.Optimization" />
<add namespace="Chruch.Net" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>

View File

@ -1,133 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net.Areas.dashboard.Controllers
{
public class FamilyMembersController : Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: dashboard/FamilyMembers
public ActionResult Index()
{
var familyMembers = db.Users.Include(f => f.Career);
return View(familyMembers.ToList());
}
// GET: dashboard/FamilyMembers/Details/5
public ActionResult Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FamilyMember familyMember = db.Users.Find(id);
if (familyMember == null)
{
return HttpNotFound();
}
return View(familyMember);
}
// GET: dashboard/FamilyMembers/Create
public ActionResult Create()
{
ViewBag.CareerId = new SelectList(db.Careers, "CareerId", "Name");
return View();
}
// POST: dashboard/FamilyMembers/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,FirstName,LastName,Gender,Birthday,Married,Baptized,DateOfBaptized,DateOfWalkIn,Address,ComunityAppId,CareerId,ProfileImage,Email,EmailConfirmed,PasswordHash,SecurityStamp,PhoneNumber,PhoneNumberConfirmed,TwoFactorEnabled,LockoutEndDateUtc,LockoutEnabled,AccessFailedCount,UserName")] FamilyMember familyMember)
{
if (ModelState.IsValid)
{
db.Users.Add(familyMember);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CareerId = new SelectList(db.Careers, "CareerId", "Name", familyMember.CareerId);
return View(familyMember);
}
// GET: dashboard/FamilyMembers/Edit/5
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FamilyMember familyMember = db.Users.Find(id);
if (familyMember == null)
{
return HttpNotFound();
}
ViewBag.CareerId = new SelectList(db.Careers, "CareerId", "Name", familyMember.CareerId);
return View(familyMember);
}
// POST: dashboard/FamilyMembers/Edit/5
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,FirstName,LastName,Gender,Birthday,Married,Baptized,DateOfBaptized,DateOfWalkIn,Address,ComunityAppId,CareerId,ProfileImage,Email,EmailConfirmed,PasswordHash,SecurityStamp,PhoneNumber,PhoneNumberConfirmed,TwoFactorEnabled,LockoutEndDateUtc,LockoutEnabled,AccessFailedCount,UserName")] FamilyMember familyMember)
{
if (ModelState.IsValid)
{
db.Entry(familyMember).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CareerId = new SelectList(db.Careers, "CareerId", "Name", familyMember.CareerId);
return View(familyMember);
}
// GET: dashboard/FamilyMembers/Delete/5
public ActionResult Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FamilyMember familyMember = db.Users.Find(id);
if (familyMember == null)
{
return HttpNotFound();
}
return View(familyMember);
}
// POST: dashboard/FamilyMembers/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(string id)
{
FamilyMember familyMember = db.Users.Find(id);
db.Users.Remove(familyMember);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}

View File

@ -1,136 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net.Areas.dashboard.Controllers
{
public class HappinessBESTsController : Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: dashboard/HappinessBESTs
public ActionResult Index(string groupId)
{
var happinessBESTs = db.HappinessBESTs.Include(h => h.HappinessGroup).Where(h=>h.GroupId==groupId);
return View(happinessBESTs.ToList());
}
// GET: dashboard/HappinessBESTs/Details/5
public ActionResult Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
HappinessBEST happinessBEST = db.HappinessBESTs.Find(id);
if (happinessBEST == null)
{
return HttpNotFound();
}
return View(happinessBEST);
}
// GET: dashboard/HappinessBESTs/Create
public ActionResult Create(string id)
{
ViewBag.GroupId = new SelectList(db.HappinessGroups, "GroupId", "Name", id);
HappinessBEST happinessBEST = new HappinessBEST();
happinessBEST.BestId = Church.Net.Utility.Format.Get33BaseGuid();
happinessBEST.GroupId = id;
return View(happinessBEST);
}
// POST: dashboard/HappinessBESTs/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "BestId,GroupId,Name,Email,Phone")] HappinessBEST happinessBEST)
{
if (ModelState.IsValid)
{
db.HappinessBESTs.Add(happinessBEST);
db.SaveChanges();
return RedirectToAction("Details", "HappinessGroups", new { id= happinessBEST.GroupId});
}
ViewBag.GroupId = new SelectList(db.HappinessGroups, "GroupId", "Name", happinessBEST.GroupId);
return View(happinessBEST);
}
// GET: dashboard/HappinessBESTs/Edit/5
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
HappinessBEST happinessBEST = db.HappinessBESTs.Find(id);
if (happinessBEST == null)
{
return HttpNotFound();
}
ViewBag.GroupId = new SelectList(db.HappinessGroups, "GroupId", "Name", happinessBEST.GroupId);
return View(happinessBEST);
}
// POST: dashboard/HappinessBESTs/Edit/5
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "BestId,GroupId,Name,Email,Phone")] HappinessBEST happinessBEST)
{
if (ModelState.IsValid)
{
db.Entry(happinessBEST).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.GroupId = new SelectList(db.HappinessGroups, "GroupId", "Name", happinessBEST.GroupId);
return View(happinessBEST);
}
// GET: dashboard/HappinessBESTs/Delete/5
public ActionResult Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
HappinessBEST happinessBEST = db.HappinessBESTs.Find(id);
if (happinessBEST == null)
{
return HttpNotFound();
}
return View(happinessBEST);
}
// POST: dashboard/HappinessBESTs/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(string id)
{
HappinessBEST happinessBEST = db.HappinessBESTs.Find(id);
db.HappinessBESTs.Remove(happinessBEST);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}

View File

@ -1,159 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net.Areas.dashboard.Controllers
{
public class HappinessGroupsController : Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: dashboard/HappinessGroups
public ActionResult Index()
{
return View(db.HappinessGroups.ToList());
}
// GET: dashboard/HappinessGroups/Details/5
public ActionResult Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
HappinessGroup happinessGroup = db.HappinessGroups.Find(id);
if (happinessGroup == null)
{
return HttpNotFound();
}
return View(happinessGroup);
}
// GET: dashboard/HappinessGroups/Create
public ActionResult Create()
{
HappinessGroup happinessGroup = new HappinessGroup();
happinessGroup.GroupId = Church.Net.Utility.Format.Get33BaseGuid();
happinessGroup.BeginTime = new DateTime(2019, 11, 01, 16, 00, 0);
return View(happinessGroup);
}
// POST: dashboard/HappinessGroups/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "GroupId,Name,BeginTime,Address,CityAndZipCode,InvitationText")] HappinessGroup happinessGroup)
{
if (ModelState.IsValid)
{
db.HappinessGroups.Add(happinessGroup);
for (int i = 1; i <= 8; i++)
{
HappinessWeek week = new HappinessWeek();
week.SEQ = i;
week.Address = happinessGroup.Address;
week.Date = happinessGroup.BeginTime.AddDays((i - 1) * 7);
week.InvitationText = happinessGroup.InvitationText;
week.GroupId = happinessGroup.GroupId;
week.WeekId = Church.Net.Utility.Format.Get33BaseGuid();
db.HappinessWeeks.Add(week);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(happinessGroup);
}
// GET: dashboard/HappinessGroups/Edit/5
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
HappinessGroup happinessGroup = db.HappinessGroups.Find(id);
if (happinessGroup == null)
{
return HttpNotFound();
}
return View(happinessGroup);
}
// POST: dashboard/HappinessGroups/Edit/5
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "GroupId,Name,BeginTime,Address,CityAndZipCode,InvitationText")] HappinessGroup happinessGroup)
{
if (ModelState.IsValid)
{
db.Entry(happinessGroup).State = EntityState.Modified;
List<HappinessWeek> weeks = db.HappinessWeeks.Where(h => h.GroupId == happinessGroup.GroupId).ToList();
foreach (var item in weeks)
{
item.Address = happinessGroup.Address;
item.CityAndZipCode = happinessGroup.CityAndZipCode;
item.InvitationText = happinessGroup.InvitationText;
item.Date = happinessGroup.BeginTime.AddDays((item.SEQ - 1) * 7);
db.Entry(item).State = EntityState.Modified;
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(happinessGroup);
}
// GET: dashboard/HappinessGroups/Delete/5
public ActionResult Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
HappinessGroup happinessGroup = db.HappinessGroups.Find(id);
if (happinessGroup == null)
{
return HttpNotFound();
}
return View(happinessGroup);
}
// POST: dashboard/HappinessGroups/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(string id)
{
HappinessGroup happinessGroup = db.HappinessGroups.Find(id);
db.HappinessGroups.Remove(happinessGroup);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}

View File

@ -1,160 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net.Areas.dashboard.Controllers
{
public class NewVisitorsController : Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: dashboard/NewVisitors
public ActionResult Index()
{
var visitors = db.NewVisitors.Include(n => n.Religion);
visitors = visitors.Where(n => n.VisitingDate > new DateTime(2019, 01, 01));
return View(visitors.OrderBy(n => n.VisitingDate).ToList());
}
// GET: dashboard/NewVisitors/Details/5
public ActionResult Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
NewVisitor newVisitor = db.NewVisitors.Include(n => n.Religion).FirstOrDefault(n => n.Id == id);
if (newVisitor == null)
{
return HttpNotFound();
}
return View(newVisitor);
}
// GET: dashboard/NewVisitors/Create
public ActionResult Create()
{
return View();
}
// POST: dashboard/NewVisitors/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,FirstName,LastName,Gender,Address,Phone,Email,ComunityAppId,VisitingDate,Note")] NewVisitor newVisitor)
{
if (ModelState.IsValid)
{
db.NewVisitors.Add(newVisitor);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(newVisitor);
}
// GET: dashboard/NewVisitors/Edit/5
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
NewVisitor newVisitor = db.NewVisitors.Find(id);
if (newVisitor == null)
{
return HttpNotFound();
}
ViewBag.ReligionId = new SelectList(db.Religions, "ReligionId", "Name", newVisitor.ReligionId);
return View(newVisitor);
}
// POST: dashboard/NewVisitors/Edit/5
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,FirstName,LastName,Gender,Address,Phone,Email,ComunityAppId,VisitingDate,Note,ReligionId")] NewVisitor newVisitor)
{
if (ModelState.IsValid)
{
db.Entry(newVisitor).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ReligionId = new SelectList(db.Religions, "ReligionId", "Name", newVisitor.ReligionId);
return View(newVisitor);
}
// GET: dashboard/NewVisitors/Delete/5
public ActionResult Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
NewVisitor newVisitor = db.NewVisitors.Find(id);
if (newVisitor == null)
{
return HttpNotFound();
}
return View(newVisitor);
}
// POST: dashboard/NewVisitors/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(string id)
{
NewVisitor newVisitor = db.NewVisitors.Find(id);
db.NewVisitors.Remove(newVisitor);
db.SaveChanges();
if (System.IO.File.Exists(Server.MapPath($"/NewVisitorsPics/{id}.jpg")))
{
System.IO.File.Delete(Server.MapPath($"/NewVisitorsPics/{id}.jpg"));
}
return RedirectToAction("Index");
}
public FileContentResult DownloadCSV()
{
var visitors = db.NewVisitors.Include(n => n.Religion).Where(n => n.VisitingDate > new DateTime(2019, 01, 01)).OrderBy(n => n.VisitingDate).ToList();
StringBuilder csv = new StringBuilder();
csv.AppendLine("Img,Last Name,First Name,Gender,Phone,Note,首次參加主日時間");
foreach (var visitor in visitors)
{
string imgPath = "http://arcadia.nlccoc.org/" +(System.IO.File.Exists(Server.MapPath($"/NewVisitorsPics/{visitor.Id}.jpg")) ? "NewVisitorsPics/" + visitor.Id + ".jpg" : "Images/New Visitor-NonImage.jpg");
csv.AppendLine($"{imgPath},{visitor.LastName},{visitor.FirstName},{visitor.Gender},{visitor.Phone},{visitor.Note},{visitor.VisitingDate}");
}
return File(new System.Text.UTF8Encoding().GetBytes(csv.ToString()), "text/csv", "NewVisitors.csv");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}

View File

@ -1,128 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net.Areas.dashboard.Controllers
{
public class ReligionsController : Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: dashboard/Religions
public ActionResult Index()
{
return View(db.Religions.ToList());
}
// GET: dashboard/Religions/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Religion religion = db.Religions.Find(id);
if (religion == null)
{
return HttpNotFound();
}
return View(religion);
}
// GET: dashboard/Religions/Create
public ActionResult Create()
{
return View();
}
// POST: dashboard/Religions/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ReligionId,Name")] Religion religion)
{
if (ModelState.IsValid)
{
db.Religions.Add(religion);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(religion);
}
// GET: dashboard/Religions/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Religion religion = db.Religions.Find(id);
if (religion == null)
{
return HttpNotFound();
}
return View(religion);
}
// POST: dashboard/Religions/Edit/5
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ReligionId,Name")] Religion religion)
{
if (ModelState.IsValid)
{
db.Entry(religion).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(religion);
}
// GET: dashboard/Religions/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Religion religion = db.Religions.Find(id);
if (religion == null)
{
return HttpNotFound();
}
return View(religion);
}
// POST: dashboard/Religions/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Religion religion = db.Religions.Find(id);
db.Religions.Remove(religion);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}

View File

@ -1,156 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Chruch.Net.Controllers;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net.Areas.dashboard.Controllers
{
public class WhoIsSpiesController : Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: dashboard/WhoIsSpies
public ActionResult Index()
{
return View(db.WhoIsSpy.ToList());
}
// GET: dashboard/WhoIsSpies/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
WhoIsSpy whoIsSpy = db.WhoIsSpy.Find(id);
if (whoIsSpy == null)
{
return HttpNotFound();
}
return View(whoIsSpy);
}
// GET: dashboard/WhoIsSpies/Create
public ActionResult Create()
{
return View();
}
// POST: dashboard/WhoIsSpies/Create
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(WhoIsSpy whoIsSpy)
{
if (ModelState.IsValid)
{
db.WhoIsSpy.Add(whoIsSpy);
db.SaveChanges();
SaveImageFromRequest("Answer1Image", Server.MapPath("~/Images/IceBreak/WhoIsSpy/"), whoIsSpy.Answer1Image);
SaveImageFromRequest("Answer2Image", Server.MapPath("~/Images/IceBreak/WhoIsSpy/"), whoIsSpy.Answer2Image);
return RedirectToAction("Index");
}
return View(whoIsSpy);
}
// GET: dashboard/WhoIsSpies/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
WhoIsSpy whoIsSpy = db.WhoIsSpy.Find(id);
if (whoIsSpy == null)
{
return HttpNotFound();
}
return View(whoIsSpy);
}
// POST: dashboard/WhoIsSpies/Edit/5
// 若要免於過量張貼攻擊,請啟用想要繫結的特定屬性,如需
// 詳細資訊,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,Answer1Cht,Answer1Chs,Answer1En,Answer2Cht,Answer2Chs,Answer2En,Answer1Image,Answer2Image")] WhoIsSpy whoIsSpy)
{
if (ModelState.IsValid)
{
db.Entry(whoIsSpy).State = EntityState.Modified;
db.SaveChanges();
SaveImageFromRequest("Answer1Image", Server.MapPath("~/Images/IceBreak/WhoIsSpy/"), whoIsSpy.Answer1Image);
SaveImageFromRequest("Answer2Image", Server.MapPath("~/Images/IceBreak/WhoIsSpy/"), whoIsSpy.Answer2Image);
return RedirectToAction("Index");
}
return View(whoIsSpy);
}
// GET: dashboard/WhoIsSpies/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
WhoIsSpy whoIsSpy = db.WhoIsSpy.Find(id);
if (whoIsSpy == null)
{
return HttpNotFound();
}
return View(whoIsSpy);
}
// POST: dashboard/WhoIsSpies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
WhoIsSpy whoIsSpy = db.WhoIsSpy.Find(id);
db.WhoIsSpy.Remove(whoIsSpy);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private void SaveImageFromRequest(string requestParameterName, string filePath,string newFileName)
{
var file = HttpContext.Request.Files[requestParameterName];
bool hasFile = file != null && !string.IsNullOrEmpty(file.FileName);
//string newFileName = hasFile ? $"{model.Id}{file.FileName.Substring(file.FileName.LastIndexOf("."))}" : "";
Directory.CreateDirectory(filePath);
if (hasFile)
{
Church.Net.Utility.Image.SaveThumbnail(new Bitmap(file.InputStream),
filePath + "\\" + newFileName, 200, 200);
}
}
}
}

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Chruch.Net.Areas.dashboard.Controllers
{
[Authorize]
public class _DashboardBaseController : Controller
{
}
}

View File

@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using Church.Net.Entity;
namespace Chruch.Net.Areas.dashboard.Models
{
public class FamilyMemberCreateViewModel
{
[StringLength(50)]
public string FirstName { get; set; }
[StringLength(50)]
public string LastName { get; set; }
public Enumeration.Gender Gender { get; set; }
public bool Married { get; set; }
public bool Baptized { get; set; }
public Enumeration.Month BaptizedMonth { get; set; }
public int BaptizedDay { get; set; }
public int BaptizedYear { get; set; }
public Enumeration.Month BirthMonth { get; set; }
public int BirthDay { get; set; }
public int BirthYear { get; set; }
[StringLength(500)]
public string Address { get; set; }
[StringLength(50)]
public string ComunityAppId { get; set; }
public string PhoneNumber { get; set; }
[StringLength(500)]
public string Email { get; set; }
public string ProfileImage { get; set; }
[Required]
[StringLength(100, ErrorMessage = "{0} 的長度至少必須為 {2} 個字元。", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "密碼")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "確認密碼")]
[System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "密碼和確認密碼不相符。")]
public string ConfirmPassword { get; set; }
public DateTime GetBirthDate()
{
return new DateTime(BirthYear,(int)BirthMonth,BirthDay);
}
public DateTime GetBaptizedDate()
{
return new DateTime(BaptizedYear, (int)BaptizedMonth, BaptizedDay);
}
}
}

View File

@ -204,25 +204,8 @@
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="Areas\admin\adminAreaRegistration.cs" />
<Compile Include="Areas\admin\Controllers\DashboardController.cs" />
<Compile Include="Areas\dashboard\Controllers\FamilyMembersController.cs" />
<Compile Include="Areas\dashboard\Controllers\HappinessBESTsController.cs" />
<Compile Include="Areas\dashboard\Controllers\HappinessGroupsController.cs" />
<Compile Include="Areas\dashboard\Controllers\NewVisitorsController.cs" />
<Compile Include="Areas\dashboard\Controllers\ReligionsController.cs" />
<Compile Include="Areas\dashboard\Controllers\WhoIsSpiesController.cs" />
<Compile Include="Areas\dashboard\Controllers\_DashboardBaseController.cs" />
<Compile Include="Areas\dashboard\dashboardAreaRegistration.cs" />
<Compile Include="Areas\dashboard\Models\FamilyMemberCreateViewModel.cs" />
<Compile Include="Areas\English\Controllers\VocabulariesController.cs" />
<Compile Include="Areas\English\EnglishAreaRegistration.cs" />
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\HappinessController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Controllers\IceBreakController.cs" />
<Compile Include="Controllers\ManageController.cs" />
<Compile Include="Controllers\NewVisitorController.cs" />
<Compile Include="Controllers\Register2019Controller.cs" />
<Compile Include="Controllers\_BaseController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
@ -4230,19 +4213,6 @@
<Content Include="Areas\dashboard\Views\WhoIsSpies\Details.cshtml" />
<Content Include="Areas\dashboard\Views\WhoIsSpies\Edit.cshtml" />
<Content Include="Areas\dashboard\Views\WhoIsSpies\Index.cshtml" />
<Content Include="Areas\English\Views\web.config" />
<Content Include="Areas\English\Views\Shared\_Layout.cshtml" />
<Content Include="Areas\English\Views\_ViewStart.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Create.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Delete.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Details.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Edit.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Index.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Memorized.cshtml" />
<Content Include="Areas\English\Views\Shared\_SpellPractice.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Visualize.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Apply.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\Review.cshtml" />
<Content Include="Areas\dashboard\Views\HappinessGroups\Create.cshtml" />
<Content Include="Areas\dashboard\Views\HappinessGroups\Delete.cshtml" />
<Content Include="Areas\dashboard\Views\HappinessGroups\Details.cshtml" />
@ -4253,7 +4223,6 @@
<Content Include="Areas\dashboard\Views\HappinessBESTs\Details.cshtml" />
<Content Include="Areas\dashboard\Views\HappinessBESTs\Edit.cshtml" />
<Content Include="Areas\dashboard\Views\HappinessBESTs\Index.cshtml" />
<Content Include="Areas\English\Views\Vocabularies\FlashCard.cshtml" />
<None Include="Properties\PublishProfiles\FolderProfile.pubxml" />
<None Include="Scripts\jquery-3.3.1.intellisense.js" />
<Content Include="Scripts\helpers\hs.bg-video.js" />
@ -4496,8 +4465,9 @@
<ItemGroup>
<Folder Include="App_Data\" />
<Folder Include="Areas\admin\Models\" />
<Folder Include="Areas\dashboard\Controllers\" />
<Folder Include="Areas\dashboard\Models\" />
<Folder Include="Areas\dashboard\Views\_DashboardBase\" />
<Folder Include="Areas\English\Models\" />
<Folder Include="Content\vendor\master-slider\" />
<Folder Include="Scripts\dashboard\" />
<Folder Include="Views\_Base\" />
@ -4511,20 +4481,6 @@
<ItemGroup>
<Service Include="{4A0DDDB5-7A95-4FBF-97CC-616D07737A77}" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Chruch.Net.BLL.Core\Church.Net.BLL.Core.csproj">
<Project>{ef712f0f-d4a3-452b-94fd-09261c558347}</Project>
<Name>Church.Net.BLL.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Church.Net.BLL\Church.Net.BLL.csproj">
<Project>{e00016c7-1d23-482b-b6fd-1da93f3a8048}</Project>
<Name>Church.Net.BLL</Name>
</ProjectReference>
<ProjectReference Include="..\Church.Net.Utility\Church.Net.Utility.csproj">
<Project>{606e98ab-096a-46ed-8e2e-4eb5ce4ec553}</Project>
<Name>Church.Net.Utility</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@ -1,488 +0,0 @@
using System;
using System.Globalization;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Chruch.Net.Models;
using Church.Net.Entity;
namespace Chruch.Net.Controllers
{
[Authorize]
public class AccountController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
{
UserManager = userManager;
SignInManager = signInManager;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
//
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// 這不會計算為帳戶鎖定的登入失敗
// 若要啟用密碼失敗來觸發帳戶鎖定,請變更為 shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "登入嘗試失試。");
return View(model);
}
}
//
// GET: /Account/VerifyCode
[AllowAnonymous]
public async Task<ActionResult> VerifyCode(string provider, string returnUrl, bool rememberMe)
{
// 需要使用者已透過使用者名稱/密碼或外部登入進行登入
if (!await SignInManager.HasBeenVerifiedAsync())
{
return View("Error");
}
return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });
}
//
// POST: /Account/VerifyCode
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> VerifyCode(VerifyCodeViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// 下列程式碼保護兩個因素碼不受暴力密碼破解攻擊。
// 如果使用者輸入不正確的代碼來表示一段指定的時間,則使用者帳戶
// 會有一段指定的時間遭到鎖定。
// 您可以在 IdentityConfig 中設定帳戶鎖定設定
var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(model.ReturnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "代碼無效。");
return View(model);
}
}
//
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
return View();
}
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new FamilyMember { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
UserManager.AddToRole(user.Id, "FamilyMember");
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// 如需如何進行帳戶確認及密碼重設的詳細資訊,請前往 https://go.microsoft.com/fwlink/?LinkID=320771
// 傳送包含此連結的電子郵件
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "確認您的帳戶", "請按一下此連結確認您的帳戶 <a href=\"" + callbackUrl + "\">這裏</a>");
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
// 如果執行到這裡,發生某項失敗,則重新顯示表單
return View(model);
}
//
// GET: /Account/ConfirmEmail
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string userId, string code)
{
if (userId == null || code == null)
{
return View("Error");
}
var result = await UserManager.ConfirmEmailAsync(userId, code);
return View(result.Succeeded ? "ConfirmEmail" : "Error");
}
//
// GET: /Account/ForgotPassword
[AllowAnonymous]
public ActionResult ForgotPassword()
{
return View();
}
//
// POST: /Account/ForgotPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
{
// 不顯示使用者不存在或未受確認
return View("ForgotPasswordConfirmation");
}
// 如需如何進行帳戶確認及密碼重設的詳細資訊,請前往 https://go.microsoft.com/fwlink/?LinkID=320771
// 傳送包含此連結的電子郵件
// string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
// var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "重設密碼", "請按 <a href=\"" + callbackUrl + "\">這裏</a> 重設密碼");
// return RedirectToAction("ForgotPasswordConfirmation", "Account");
}
// 如果執行到這裡,發生某項失敗,則重新顯示表單
return View(model);
}
//
// GET: /Account/ForgotPasswordConfirmation
[AllowAnonymous]
public ActionResult ForgotPasswordConfirmation()
{
return View();
}
//
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : View();
}
//
// POST: /Account/ResetPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
// 不顯示使用者不存在
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
AddErrors(result);
return View();
}
//
// GET: /Account/ResetPasswordConfirmation
[AllowAnonymous]
public ActionResult ResetPasswordConfirmation()
{
return View();
}
//
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
// 要求重新導向至外部登入提供者
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
//
// GET: /Account/SendCode
[AllowAnonymous]
public async Task<ActionResult> SendCode(string returnUrl, bool rememberMe)
{
var userId = await SignInManager.GetVerifiedUserIdAsync();
if (userId == null)
{
return View("Error");
}
var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(userId);
var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
}
//
// POST: /Account/SendCode
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SendCode(SendCodeViewModel model)
{
if (!ModelState.IsValid)
{
return View();
}
// 產生並傳送 Token
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
{
return View("Error");
}
return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
}
//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
// 若使用者已經有登入資料,請使用此外部登入提供者登入使用者
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
case SignInStatus.Failure:
default:
// 若使用者沒有帳戶,請提示使用者建立帳戶
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
}
}
//
// POST: /Account/ExternalLoginConfirmation
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
if (User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Manage");
}
if (ModelState.IsValid)
{
// 從外部登入提供者處取得使用者資訊
var info = await AuthenticationManager.GetExternalLoginInfoAsync();
if (info == null)
{
return View("ExternalLoginFailure");
}
var user = new FamilyMember { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user);
if (result.Succeeded)
{
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
}
AddErrors(result);
}
ViewBag.ReturnUrl = returnUrl;
return View(model);
}
//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
}
//
// GET: /Account/ExternalLoginFailure
[AllowAnonymous]
public ActionResult ExternalLoginFailure()
{
return View();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_userManager != null)
{
_userManager.Dispose();
_userManager = null;
}
if (_signInManager != null)
{
_signInManager.Dispose();
_signInManager = null;
}
}
base.Dispose(disposing);
}
#region Helper
// 新增外部登入時用來當做 XSRF 保護
private const string XsrfKey = "XsrfId";
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
internal class ChallengeResult : HttpUnauthorizedResult
{
public ChallengeResult(string provider, string redirectUri)
: this(provider, redirectUri, null)
{
}
public ChallengeResult(string provider, string redirectUri, string userId)
{
LoginProvider = provider;
RedirectUri = redirectUri;
UserId = userId;
}
public string LoginProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
}
}
#endregion
}
}

View File

@ -1,174 +0,0 @@
using Church.Net.DAL.EF;
using Church.Net.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace Chruch.Net.Controllers
{
public class HappinessController : Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: Happiness
public ActionResult Best(string id)
{
HappinessBEST best;
best = db.HappinessBESTs.FirstOrDefault(h => h.BestId == id);
if (best!=null)
{
ViewBag.BestName = best.Name;
HappinessGroup group = new HappinessGroup();
group = db.HappinessGroups.First(g => g.GroupId == best.GroupId);
group.BestList = new List<HappinessBEST>();
group.BestList.Clear();
group.BestList.Add(best);
group.Weeks = new List<HappinessWeek>();
group.Weeks.Clear();
var qurry = db.HappinessWeeks.OrderBy(o => o.SEQ).ToList();
group.Weeks.Add(qurry.First(g => g.GroupId == best.GroupId & g.Date>= DateTime.Today));
string weekTitle = "";
StringBuilder invitation = new StringBuilder();
invitation.Append($".type('Hi, <strong>{best.Name}</strong>,').break()");
switch (group.Weeks.First().SEQ)
{
case 1:
weekTitle = "真幸福";
invitation.Append("我們想送你一份禮物, ");
invitation.Append("他是人生中最棒的夥伴, ");
invitation.Append("為你帶來超乎想像的幸福感, ");
invitation.Append("值得你用8個星期的時間來認識. ");
invitation.Append("幸福小組,邀你一同了解幸福! ");
break;
case 2:
weekTitle = "真相大白";
invitation.Append(".options({ speed: 155 }).type('我們想送你一份禮物,').pause(500)");
invitation.Append(".options({ speed: 125 }).delete(10)");
invitation.Append(".type('你以為我們這麼偷懶 :-)').break()");
invitation.Append(".type('每周的邀請函內容一樣嗎?').break()");
invitation.Append(".type('當然不是囉~').break()");
invitation.Append(".type('我們可是求新求變,').break()");
invitation.Append(".type('尋找人生新氣象的幸福小組呢~').break()");
invitation.Append(".type('這周想邀請你一起來,').break()");
invitation.Append(".type('破除謊言尋找幸福的真相唷~').break()");
break;
case 3:
weekTitle = "萬世巨星";
invitation.Append(".type('這星期過得好嗎? ').break()");
invitation.Append(".options({ speed: 155 }).type('這週將揭曉一位萬事巨猩唷!')");
invitation.Append(".options({ speed: 125 }).delete(4)");
invitation.Append(".type('巨星唷!').break()");
invitation.Append(".type('想知道是誰要登場了嗎;-)? ').break()");
invitation.Append(".type('千萬別錯過這週的幸福小組唷~ ').break()");
invitation.Append(".type('期待與你幸福有約。 ').break()");
invitation.Append(".type('讓我們一起來經歷平安、喜樂 ').break()");
invitation.Append(".options({ speed: 175 }).type('祝 福 滿 滿!!!')");
break;
case 4:
weekTitle = "幸福連線";
break;
case 5:
weekTitle = "當上帝來敲門";
break;
case 6:
weekTitle = "十字架的勝利";
break;
case 7:
weekTitle = "釋放與自由";
break;
case 8:
weekTitle = "幸福的教會";
break;
default:
break;
}
ViewBag.Title = $"{group.Name}-邀請函之{weekTitle}! for {best.Name}";
ViewBag.InvitationJS = invitation.ToString();
return View(group);
}
return RedirectToAction("Index", "Home");
}
public ActionResult Week(int id)
{
HappinessGroup group = new HappinessGroup();
group = db.HappinessGroups.First();
group.Weeks = new List<HappinessWeek>();
group.Weeks.Clear();
var qurry = db.HappinessWeeks.OrderBy(o => o.SEQ).ToList();
group.Weeks.Add(qurry.First(g => g.GroupId == group.GroupId & g.SEQ == id));
HappinessBEST best;
best = group.BestList.First();
ViewBag.BestName = best.Name;
string weekTitle = "";
StringBuilder invitation = new StringBuilder();
switch (group.Weeks.First().SEQ)
{
case 1:
weekTitle = "真幸福";
break;
case 2:
weekTitle = "真相大白";
invitation.Append($".type('Hi, <strong>{best.Name}</strong>,').break()");
invitation.Append(".options({ speed: 155 }).type('我們想送你一份禮物,').pause(500)");
invitation.Append(".options({ speed: 125 }).delete(10)");
invitation.Append(".type('你以為我們這麼偷懶 :-)').break()");
invitation.Append(".type('每周的邀請函內容一樣嗎?').break()");
invitation.Append(".type('當然不是囉~').break()");
invitation.Append(".type('我們可是求新求變,').break()");
invitation.Append(".type('尋找人生新氣象的幸福小組呢~').break()");
invitation.Append(".type('這周想邀請你一起來,').break()");
invitation.Append(".type('破除謊言尋找幸福的真相唷~').break()");
break;
case 3:
weekTitle = "萬世巨星";
break;
case 4:
weekTitle = "幸福連線";
break;
case 5:
weekTitle = "當上帝來敲門";
break;
case 6:
weekTitle = "十字架的勝利";
break;
case 7:
weekTitle = "釋放與自由";
break;
case 8:
weekTitle = "幸福的教會";
break;
default:
break;
}
ViewBag.Title = $"{group.Name}-邀請函之{weekTitle}! for {group.BestList.First().Name}";
ViewBag.InvitationJS = invitation.ToString();
return View("Best", group);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}

View File

@ -1,46 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Chruch.Net.Controllers
{
public class HomeController : Controller
{
public ActionResult Index(string id)
{
if (HttpContext.Request.Url.AbsoluteUri.IndexOf("gls.") > 0 || HttpContext.Request.Url.AbsoluteUri.IndexOf("glsoc.") > 0)
{
if (id == "EN")
{
return View("/Views/Register2019/Index.cshtml");
}
else
{
return View("/Views/Register2019/IndexCn.cshtml");
}
}
//return RedirectToAction("Index", "NewVisitor");
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}

View File

@ -1,483 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Chruch.Net.Models.IceBreak;
using Church.Net.DAL.EF;
using Church.Net.Entity;
using Church.Net.Utility;
using Microsoft.Ajax.Utilities;
namespace Chruch.Net.Controllers
{
public class IceBreakController : _BaseController
{
private ChurchNetContext db = new ChurchNetContext();
// GET: IceBreak
public ActionResult Index()
{
return View();
}
public ActionResult Host()
{
return View();
}
public ActionResult Hi(string id, GamePlayer model)
{
model = new GamePlayer();
model.TempGameRoomId = PlayerInfo.TempGameRoomId;
return View(model);
}
[HttpPost]
public ActionResult Hi(GamePlayer model)
{
if (ModelState.IsValid)
{
PlayerInfo = model;
PlayerInfo.Id = Church.Net.Utility.Format.Get33BaseGuid();
if (PlayerInfo.TempGameRoomId.IsNullOrWhiteSpace())
{
return RedirectToAction("WhoIsSpyPlay");
}
else
{
return RedirectToAction("WhoIsSpyPlayJoin", new { id = PlayerInfo.TempGameRoomId });
}
}
return View(model);
}
#region WhoIsSpy
#region PublicProperty
public List<Models.IceBreak.GameRoom> GameRooms
{
get
{
if (HttpContext.Application["GameRooms"] == null)
{
HttpContext.Application["GameRooms"] = new List<GameRoom>();
}
return (List<GameRoom>)HttpContext.Application["GameRooms"];
}
set => HttpContext.Application["GameRooms"] = value;
}
public string GameRoomId
{
get
{
if (HttpContext.Session["GameRoomId"] == null)
{
HttpContext.Session["GameRoomId"] = "";
}
return (string)HttpContext.Session["GameRoomId"];
}
set => HttpContext.Session["GameRoomId"] = value;
}
public GamePlayer PlayerInfo
{
get
{
if (HttpContext.Session["PlayerInfo"] == null)
{
HttpContext.Session["PlayerInfo"] = new GamePlayer();
}
return (GamePlayer)HttpContext.Session["PlayerInfo"];
}
set => HttpContext.Session["PlayerInfo"] = value;
}
#endregion
#region Console
// GET: IceBreak
public ActionResult WhoIsSpy(string id)
{
if (id.IsNullOrWhiteSpace() && GameRoomId.IsNullOrWhiteSpace())
{
return View("WhoIsSpy", new Models.IceBreak.WhoIsSpyGameRoom());
}
if (GameRooms.Any(g => g.Id == id))
{
GameRoomId = id;
}
else if(!id.IsNullOrWhiteSpace())
{
Models.IceBreak.WhoIsSpyGameRoom model = new WhoIsSpyGameRoom();
if (model.Id.IsNullOrWhiteSpace())
{
Random r = new Random();
model.Id = r.Next(1, 99).ToString("00");
}
model.Id = GameRoomId;
model.SpyAmount = 2;
model.Status = WhoIsSpyProcess.WaitForPlayer;
GameRooms.Add(model);
GameRoomId = model.Id;
}
var gameRoom = GameRooms.FirstOrDefault(room => room.Id == GameRoomId);
return View("WhoIsSpy", (WhoIsSpyGameRoom)gameRoom);
}
[HttpPost]
public ActionResult WhoIsSpyCreate(string id)
{
if (GameRooms.Any(g => g.Id == id))
{
GameRoomId = id;
}
else
{
Models.IceBreak.WhoIsSpyGameRoom model = new WhoIsSpyGameRoom();
model.Id = id;
if (model.Id.IsNullOrWhiteSpace())
{
Random r = new Random();
model.Id = r.Next(1, 99).ToString("00");
}
model.SpyAmount = 2;
model.Status = WhoIsSpyProcess.WaitForPlayer;
GameRooms.Add(model);
GameRoomId = model.Id;
}
return RedirectToAction("WhoIsSpy");
}
[HttpPost]
public ActionResult WhoIsSpyStart(Models.IceBreak.WhoIsSpyGameRoom model)
{
Random r = new Random();
WhoIsSpyGameRoom gameRoom = (WhoIsSpyGameRoom)GameRooms.FirstOrDefault(room => room.Id == GameRoomId);
if (gameRoom == null)
{
return RedirectToAction("WhoIsSpy");
}
gameRoom.SpyAmount = model.SpyAmount;
gameRoom.EmptyAmount = model.EmptyAmount;
if ((gameRoom.TotalPlayer -1) < gameRoom.SpyAmount*2)
{
ShowScriptMsg("臥底人數太多了!", MessageType.Errors);
return View("WhoIsSpy", gameRoom);
}
if (gameRoom.SpyAmount < gameRoom.EmptyAmount * 2)
{
ShowScriptMsg("空白人數太多了!", MessageType.Errors);
return View("WhoIsSpy", gameRoom);
}
//取題目
int totalAnswer = db.WhoIsSpy.Count(a=> !gameRoom.PlayedAnswerId.Contains(a.Id));
if (totalAnswer==0)
{
gameRoom.PlayedAnswerId=new List<int>();
}
WhoIsSpy answer;
answer = db.WhoIsSpy.Where(a => !gameRoom.PlayedAnswerId.Contains(a.Id)).OrderBy(a => a.Id).Skip(r.Next(0, totalAnswer - 1)).First();
gameRoom.PlayedAnswerId.Add(answer.Id);
bool reverseAnswer = r.Next(0, 100) > 50;
gameRoom.Answer = reverseAnswer
? new WhoIsSpyAnswer(answer.Answer1Cht, answer.Answer1Chs, answer.Answer1En, answer.Answer1Image)
: new WhoIsSpyAnswer(answer.Answer2Cht, answer.Answer2Chs, answer.Answer2En, answer.Answer2Image);
gameRoom.SpysAnswer = !reverseAnswer
? new WhoIsSpyAnswer(answer.Answer1Cht, answer.Answer1Chs, answer.Answer1En, answer.Answer1Image)
: new WhoIsSpyAnswer(answer.Answer2Cht, answer.Answer2Chs, answer.Answer2En, answer.Answer2Image);
//Set Player
foreach (var whoIsSpyPlayer in gameRoom.Players)
{
whoIsSpyPlayer.VoteTo = new List<string>();
whoIsSpyPlayer.IsDead = false;
whoIsSpyPlayer.GameStatus = WhoIsSpyProcess.Started;
whoIsSpyPlayer.Answer = gameRoom.Answer;
whoIsSpyPlayer.IsSpy = false;
}
//Set Spy
WhoIsSpyPlayer spy;
for (int g = 1; g <= gameRoom.SpyAmount; g++)
{
do
{
spy = gameRoom.Players[r.Next(0, gameRoom.TotalPlayer - 1)];
} while (spy.IsSpy);
spy.IsSpy = true;
spy.Answer = g <= gameRoom.EmptyAmount ? new WhoIsSpyAnswer() : gameRoom.SpysAnswer;
}
//Start Order
do
{
gameRoom.StartIndex = r.Next(0, gameRoom.TotalPlayer - 1);
} while (gameRoom.Players[gameRoom.StartIndex].IsDead);
gameRoom.Status = WhoIsSpyProcess.Started;
return RedirectToAction("WhoIsSpy");
}
public ActionResult WhoIsSpyClose()
{
GameRooms.RemoveAll(room => room.Id == GameRoomId);
GameRoomId = "";
return RedirectToAction("WhoIsSpy");
}
[HttpPost]
public ActionResult WhoIsSpyNext()
{
var gameRoom = (WhoIsSpyGameRoom)GameRooms.FirstOrDefault(room => room.Id == GameRoomId);
if (gameRoom==null)
{
return RedirectToAction("WhoIsSpy");
}
switch (gameRoom.Status)
{
case WhoIsSpyProcess.WaitForPlayer:
break;
case WhoIsSpyProcess.Started:
//開始
gameRoom.Status = WhoIsSpyProcess.Votting;
gameRoom.VoteAmount = gameRoom.Players.Count(p => p.IsSpy && !p.IsDead);
gameRoom.Players.Shuffle();
foreach (var whoIsSpyPlayer in gameRoom.Players)
{
whoIsSpyPlayer.VoteTo = new List<string>();
whoIsSpyPlayer.ReceviedVotes = 0;
whoIsSpyPlayer.VoteAmount = gameRoom.Players.Count(p => p.IsSpy && !p.IsDead);
whoIsSpyPlayer.VoteOption=new List<WhoIsSpyVoteOption>(gameRoom.Players.Where(p=>p.Id!=whoIsSpyPlayer.Id&&!p.IsDead).Select(p=>new WhoIsSpyVoteOption(p.Id,p.Name)));
}
break;
case WhoIsSpyProcess.Votting:
foreach (var whoIsSpyPlayer in gameRoom.Players.OrderByDescending(p=>p.ReceviedVotes).Take(gameRoom.Players.Count(p => p.IsSpy && !p.IsDead)))
{
whoIsSpyPlayer.IsDead = true;
}
gameRoom.Status = WhoIsSpyProcess.DisplayResult;
break;
case WhoIsSpyProcess.DisplayResult:
if (gameRoom.Players.Count(p => p.IsSpy && !p.IsDead)>= gameRoom.Players.Count(p => !p.IsSpy && !p.IsDead) || gameRoom.Players.Count(p => p.IsSpy && !p.IsDead)==0)
{
gameRoom.Status = WhoIsSpyProcess.End;
}
else
{
gameRoom.Status = WhoIsSpyProcess.Started;
}
break;
case WhoIsSpyProcess.End:
gameRoom.Status = WhoIsSpyProcess.WaitForPlayer;
break;
default:
throw new ArgumentOutOfRangeException();
}
foreach (var whoIsSpyPlayer in gameRoom.Players)
{
whoIsSpyPlayer.GameStatus = gameRoom.Status;
}
return RedirectToAction("WhoIsSpy");
}
public PartialViewResult WhoIsSpyGetPlayerList()
{
var gameRoom = GameRooms.FirstOrDefault(room => room.Id == GameRoomId);
if (gameRoom == null)
{
return null;
}
return PartialView("~/Views/IceBreak/WhoIsSpyPlayerList.cshtml", gameRoom.Players.Select(p => p.Name).ToList());
}
public PartialViewResult WhoIsSpyGetPlayerVoteList()
{
var gameRoom = GameRooms.FirstOrDefault(room => room.Id == GameRoomId);
if (gameRoom == null)
{
return null;
}
return PartialView("~/Views/IceBreak/WhoIsSpyPlayerList.cshtml", gameRoom?.Players.Where(p => !p.IsDead && p.VoteTo.Count == 0).Select(p => p.Name).ToList());
}
#endregion
#region WhoIsSpyPlayer
public ActionResult WhoIsSpyPlay()
{
if (PlayerInfo.Name.IsNullOrWhiteSpace())
{
return RedirectToAction("Hi");
}
var gameRoom = GameRooms.FirstOrDefault(room => room.Id == GameRoomId);
if (gameRoom != null && gameRoom.Players.Exists(p => p.Id == PlayerInfo.Id))
{
return View(gameRoom.Players.FirstOrDefault(p => p.Id == PlayerInfo.Id));
}
return View();
}
public ActionResult WhoIsSpyPlayJoin(string id)
{
var gameRoom = (WhoIsSpyGameRoom)GameRooms.FirstOrDefault(room => room.Id == id);
if (gameRoom == null)
{
ShowScriptMsg("遊戲室不存在,請重新輸入遊戲室編號", MessageType.Warring);
return RedirectToAction("WhoIsSpyPlay");
}
if (PlayerInfo.Name.IsNullOrWhiteSpace())
{
PlayerInfo.TempGameRoomId = id;
return RedirectToAction("Hi");
}
WhoIsSpyPlayer model;
if (!gameRoom.Players.Exists(p => p.Id == PlayerInfo.Id))
{
model = new WhoIsSpyPlayer()
{
Id = PlayerInfo.Id,
Name = PlayerInfo.Name,
RoomId = id,
GameStatus = gameRoom.Status
};
gameRoom.Players.Add(model);
GameRoomId = gameRoom.Id;
}
return RedirectToAction("WhoIsSpyPlay");
}
public ActionResult WhoIsSpyPlayVote(WhoIsSpyPlayer model)
{
try
{
var gameRoom = GameRooms.FirstOrDefault(room => room.Id == GameRoomId);
var player = gameRoom.Players.Find(p => p.Id == model.Id);
player.GameStatus = WhoIsSpyProcess.DisplayResult;
player.VoteTo = model.VoteTo;
foreach (var s in model.VoteTo)
{
gameRoom.Players.Find(p => p.Id == s).ReceviedVotes += 1;
}
}
catch (Exception e)
{
}
return RedirectToAction("WhoIsSpyPlay");
}
public ActionResult WhoIsSpyExit()
{
var gameRoom = GameRooms.FirstOrDefault(room => room.Id == GameRoomId);
gameRoom.Players.RemoveAll(p => p.Id == PlayerInfo.Id);
PlayerInfo.TempGameRoomId = "";
GameRoomId = "";
return RedirectToAction("WhoIsSpyPlay");
}
public JsonResult CheckGameRoomStatu(string id)
{
var gameRoom = GameRooms.FirstOrDefault(room => room.Id == id);
if (gameRoom==null)
{
return Json(WhoIsSpyProcess.Closed);
}
var player = gameRoom.Players.Find(p => p.Id == PlayerInfo.Id);
return Json(player.GameStatus);
}
#endregion
#endregion
}
}

View File

@ -1,389 +0,0 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Chruch.Net.Models;
namespace Chruch.Net.Controllers
{
[Authorize]
public class ManageController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public ManageController()
{
}
public ManageController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
//
// GET: /Manage/Index
public async Task<ActionResult> Index(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "已變更您的密碼。"
: message == ManageMessageId.SetPasswordSuccess ? "已設定您的密碼。"
: message == ManageMessageId.SetTwoFactorSuccess ? "已設定您的雙因素驗證。"
: message == ManageMessageId.Error ? "發生錯誤。"
: message == ManageMessageId.AddPhoneSuccess ? "已新增您的電話號碼。"
: message == ManageMessageId.RemovePhoneSuccess ? "已移除您的電話號碼。"
: "";
var userId = User.Identity.GetUserId();
var model = new IndexViewModel
{
HasPassword = HasPassword(),
PhoneNumber = await UserManager.GetPhoneNumberAsync(userId),
TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId),
Logins = await UserManager.GetLoginsAsync(userId),
BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userId)
};
return View(model);
}
//
// POST: /Manage/RemoveLogin
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> RemoveLogin(string loginProvider, string providerKey)
{
ManageMessageId? message;
var result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
message = ManageMessageId.RemoveLoginSuccess;
}
else
{
message = ManageMessageId.Error;
}
return RedirectToAction("ManageLogins", new { Message = message });
}
//
// GET: /Manage/AddPhoneNumber
public ActionResult AddPhoneNumber()
{
return View();
}
//
// POST: /Manage/AddPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// 產生並傳送 Token
var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), model.Number);
if (UserManager.SmsService != null)
{
var message = new IdentityMessage
{
Destination = model.Number,
Body = "您的安全碼為: " + code
};
await UserManager.SmsService.SendAsync(message);
}
return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number });
}
//
// POST: /Manage/EnableTwoFactorAuthentication
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EnableTwoFactorAuthentication()
{
await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true);
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", "Manage");
}
//
// POST: /Manage/DisableTwoFactorAuthentication
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DisableTwoFactorAuthentication()
{
await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false);
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", "Manage");
}
//
// GET: /Manage/VerifyPhoneNumber
public async Task<ActionResult> VerifyPhoneNumber(string phoneNumber)
{
var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), phoneNumber);
// 透過 SMS 提供者傳送 SMS以驗證電話號碼
return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
}
//
// POST: /Manage/VerifyPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await UserManager.ChangePhoneNumberAsync(User.Identity.GetUserId(), model.PhoneNumber, model.Code);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess });
}
// 如果執行到這裡,發生某項失敗,則重新顯示表單
ModelState.AddModelError("", "無法驗證號碼");
return View(model);
}
//
// POST: /Manage/RemovePhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> RemovePhoneNumber()
{
var result = await UserManager.SetPhoneNumberAsync(User.Identity.GetUserId(), null);
if (!result.Succeeded)
{
return RedirectToAction("Index", new { Message = ManageMessageId.Error });
}
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.RemovePhoneSuccess });
}
//
// GET: /Manage/ChangePassword
public ActionResult ChangePassword()
{
return View();
}
//
// POST: /Manage/ChangePassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess });
}
AddErrors(result);
return View(model);
}
//
// GET: /Manage/SetPassword
public ActionResult SetPassword()
{
return View();
}
//
// POST: /Manage/SetPassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SetPassword(SetPasswordViewModel model)
{
if (ModelState.IsValid)
{
var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.SetPasswordSuccess });
}
AddErrors(result);
}
// 如果執行到這裡,發生某項失敗,則重新顯示表單
return View(model);
}
//
// GET: /Manage/ManageLogins
public async Task<ActionResult> ManageLogins(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.RemoveLoginSuccess ? "已移除外部登入。"
: message == ManageMessageId.Error ? "發生錯誤。"
: "";
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user == null)
{
return View("Error");
}
var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId());
var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList();
ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1;
return View(new ManageLoginsViewModel
{
CurrentLogins = userLogins,
OtherLogins = otherLogins
});
}
//
// POST: /Manage/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LinkLogin(string provider)
{
// 要求重新導向至外部登入提供者,以連結目前使用者的登入
return new AccountController.ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage"), User.Identity.GetUserId());
}
//
// GET: /Manage/LinkLoginCallback
public async Task<ActionResult> LinkLoginCallback()
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
if (loginInfo == null)
{
return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
return result.Succeeded ? RedirectToAction("ManageLogins") : RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
protected override void Dispose(bool disposing)
{
if (disposing && _userManager != null)
{
_userManager.Dispose();
_userManager = null;
}
base.Dispose(disposing);
}
#region Helper
// 新增外部登入時用來當做 XSRF 保護
private const string XsrfKey = "XsrfId";
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
private bool HasPassword()
{
var user = UserManager.FindById(User.Identity.GetUserId());
if (user != null)
{
return user.PasswordHash != null;
}
return false;
}
private bool HasPhoneNumber()
{
var user = UserManager.FindById(User.Identity.GetUserId());
if (user != null)
{
return user.PhoneNumber != null;
}
return false;
}
public enum ManageMessageId
{
AddPhoneSuccess,
ChangePasswordSuccess,
SetTwoFactorSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
RemovePhoneSuccess,
Error
}
#endregion
}
}

View File

@ -6,109 +6,15 @@ using System.Linq;
using System.Web;
using System.Web.Mvc;
using Chruch.Net.Models;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net.Controllers
{
public class NewVisitorController : _BaseController
public class NewVisitorController :Controller
{
private ChurchNetContext db = new ChurchNetContext();
// GET: NewVisitor
public ActionResult Index(Church.Net.Entity.NewVisitor model)
public ActionResult Index()
{
ViewBag.ReligionId = new SelectList(db.Religions, "ReligionId", "Name");
model.Gender = Enumeration.Gender.Male;
return View(model);
}
public ActionResult Registration(Church.Net.Entity.NewVisitor model)
{
if (model != null)
{
model.Id = Church.Net.Utility.Format.Get33BaseGuid();
model.VisitingDate=DateTime.Now;
ModelState.Clear();
TryValidateModel(model);
//ValidateModel(dNSServer);
}
if (ModelState.IsValid)
{
var file = HttpContext.Request.Files["AttachFile"];
bool hasFile = file != null && !string.IsNullOrEmpty(file.FileName);
string filePath = Server.MapPath("~/NewVisitorsPics/");
//string newFileName = hasFile ? $"{model.Id}{file.FileName.Substring(file.FileName.LastIndexOf("."))}" : "";
string newFileName = hasFile ? $"{model.Id}.jpg" : "";
Directory.CreateDirectory(filePath);
try
{
var logic = new Church.Net.BLL.NewVisitorBLL(this.ConnString);
logic.Add(model);
if (hasFile)
{
Church.Net.Utility.Image.SaveThumbnail(new Bitmap(file.InputStream),
filePath + "\\" + newFileName, 1920, 1080);
//file.SaveAs(filePath + "\\" + newFileName);
}
ShowScriptMsg("一次歡迎,永遠歡迎!",MessageType.Success);
}
catch (Exception e)
{
ShowMsgByEx(e);
}
}
return RedirectToAction("Index");
// return View(model);
}
[HttpGet]
public ActionResult Slider()
{
NewVisitorViewClass model = new NewVisitorViewClass()
{
BeginDate = DateTime.Today,
EndDate = DateTime.Today
};
return View("ImageTextSliderChooseDate", model);
}
[HttpPost]
public ActionResult Slider(NewVisitorViewClass model)
{
DateTime beginDate = DateTime.Today;
DateTime endDate = DateTime.Today.AddDays(1);
beginDate = model.BeginDate;
endDate = model.EndDate.AddDays(1);
var list = new Church.Net.BLL.NewVisitorBLL(this.ConnString).GetAll(visitor =>
visitor.VisitingDate >= beginDate && visitor.VisitingDate <= endDate);
return View(list);
}
public ActionResult Today()
{
DateTime beginDate = DateTime.Today;
DateTime endDate = DateTime.Today.AddDays(1);
var list = new Church.Net.BLL.NewVisitorBLL(this.ConnString).GetAll(visitor =>
visitor.VisitingDate >= beginDate && visitor.VisitingDate <= endDate);
return View("Slider", list);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
return View();
}
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Chruch.Net.Controllers
{
public class Register2019Controller : Controller
{
// GET: Register2018
public ActionResult Index(string id)
{
if (id=="EN")
{
return View();
}
else
{
return View("IndexCn");
}
}
}
}

View File

@ -1,196 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace Chruch.Net.Controllers
{
public class _BaseController : Controller
{
#region
protected enum MessageType
{
Warring,
Done,
Success,
Errors,
None
}
protected enum CRUDType
{
None,
Processing,
Create,
Update,
Delete
}
protected enum Active
{
Processing,
Reading,
Adding,
Editing
}
#endregion
private string ResultMessage
{
get
{
if (System.Web.HttpContext.Current.Session["ResultMessage"] != null)
{
return System.Web.HttpContext.Current.Session["ResultMessage"].ToString();
}
return "";
}
set
{
System.Web.HttpContext.Current.Session["ResultMessage"] = value;
}
}
protected string ConnString
{
get
{
if (System.Web.HttpContext.Current.Session["ConnString"] != null)
{
return System.Web.HttpContext.Current.Session["ConnString"].ToString();
}
ConnString= System.Configuration.ConfigurationManager.ConnectionStrings["entityFramework"].ConnectionString;
return ConnString;
}
set
{
System.Web.HttpContext.Current.Session["ConnString"] = value;
}
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (!filterContext.HttpContext.Request.IsAjaxRequest())
{
var response = filterContext.HttpContext.Response;
if (response.ContentType == "text/html" &&
!(filterContext.Result is RedirectToRouteResult) &&
!(filterContext.Result is RedirectResult))
{
if (!string.IsNullOrEmpty(ResultMessage))
{
ViewBag.StartScript = ResultMessage;
ResultMessage = "";
}
}
}
}
#region MessageBox
protected void ShowScriptMsg(string description, MessageType MsType = MessageType.None)
{
ShowScriptMsg(description, "", MsType);
}
protected void ShowScriptMsg(string descritpion, string title, MessageType MsType = MessageType.None)
{
StringBuilder stringBuilder = new StringBuilder();
title = title.Replace(Environment.NewLine, "<br>").Replace("'", "\"");
descritpion = descritpion.Replace(Environment.NewLine, "<br>").Replace("'", "\"");
stringBuilder.AppendLine(" swal({ ");
if (!string.IsNullOrWhiteSpace(descritpion))
{
stringBuilder.AppendLine($" html: '{descritpion}', ");
}
switch (MsType)
{
case MessageType.Success:
stringBuilder.AppendLine($" title: '{title} {LanHelper.GetText("Success")}', ");
stringBuilder.AppendLine(" type: \"success\" ");
break;
case MessageType.Warring:
stringBuilder.AppendLine($" title: '{title} {LanHelper.GetText("Warning")}', ");
stringBuilder.AppendLine(" type: \"warning\" ");
break;
case MessageType.Errors:
stringBuilder.AppendLine($" title: '{title} {LanHelper.GetText("Fail")}', ");
stringBuilder.AppendLine(" type: \"error\" ");
break;
case MessageType.Done:
stringBuilder.AppendLine($" title: '{title} {LanHelper.GetText("Done")}', ");
stringBuilder.AppendLine(" type: \"success\" ");
break;
default:
break;
}
stringBuilder.AppendLine("}); ");
ResultMessage = stringBuilder.ToString();
}
protected void ShowScriptMsgAndRedirect(string descritpion, string url, MessageType MsType = MessageType.None)
{
ShowScriptMsgAndRedirect(descritpion, "", url, MsType);
}
protected void ShowScriptMsgAndRedirect(string descritpion, string title, string url, MessageType MsType = MessageType.None)
{
StringBuilder stringBuilder = new StringBuilder();
title = title.Replace(Environment.NewLine, "<br>").Replace("'", "\"");
descritpion = descritpion.Replace(Environment.NewLine, "<br>").Replace("'", "\"");
stringBuilder.AppendLine(" swal({ ");
if (!string.IsNullOrWhiteSpace(descritpion))
{
stringBuilder.AppendLine($" html: '{descritpion}', ");
}
switch (MsType)
{
case MessageType.Success:
stringBuilder.AppendLine($" title: \"{title} {LanHelper.GetText("Success")}\", ");
stringBuilder.AppendLine(" type: \"success\" ");
break;
case MessageType.Warring:
stringBuilder.AppendLine($" title: \"{title} {LanHelper.GetText("Warning")}\", ");
stringBuilder.AppendLine(" type: \"warning\" ");
break;
case MessageType.Errors:
stringBuilder.AppendLine($" title: \"{title} {LanHelper.GetText("Fail")}\", ");
stringBuilder.AppendLine(" type: \"error\" ");
break;
case MessageType.Done:
stringBuilder.AppendLine($" title: \"{title} {LanHelper.GetText("Done")}\", ");
stringBuilder.AppendLine(" type: \"success\" ");
break;
default:
break;
}
stringBuilder.Append("}).then(function () {");
stringBuilder.Append("$.ShowP;");
stringBuilder.Append($"window.location.href = '{url}';");
stringBuilder.Append("});");
ResultMessage = stringBuilder.ToString();
}
protected void ShowMsgByEx(Exception ex)
{
if (ex.GetType() == typeof(ArgumentException))
{
ShowScriptMsg(LanHelper.GetText(ex.Message), "", MessageType.Warring);
}
else
{
ShowScriptMsg(ex.Message, "", MessageType.Errors);
}
}
#endregion
}
}

View File

@ -6,9 +6,6 @@ using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Church.Net.DAL.EF;
using Church.Net.Entity;
namespace Chruch.Net
{
public class MvcApplication : System.Web.HttpApplication

View File

@ -1,4 +1,4 @@
@model Church.Net.Entity.NewVisitor

@{
Layout = null;
}
@ -18,7 +18,7 @@
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta charset="UTF-8" />
<!-- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> -->
<title>歡迎新朋友</title>
<title>New</title>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<link href="https://fonts.googleapis.com/css?family=Raleway:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
@ -33,7 +33,7 @@
<div class="container">
<header>
<h1>新生命靈糧堂-亞凱迪亞</h1>
<h1>LOGO Here</h1>
</header>
<section>
<div id="container_demo">
@ -44,66 +44,32 @@
@using (Html.BeginForm("Registration", "NewVisitor", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<h1> 歡迎新朋友 </h1>
<h1> Weclome Text </h1>
<p>
<label for="usernamesignup" class="uname">
姓氏
First Name
</label>
@Html.ValidationMessageFor(c => c.LastName)
@Html.TextBoxFor(c => c.LastName, new
<input />
@*@Html.ValidationMessageFor(c => c)
@Html.TextBoxFor(c => c, new
{
placeholder = "請輸入您的姓氏"
})
})*@
</p>
<p>
<label for="usernamesignup" class="uname">
名字
Last Name
</label>
@Html.ValidationMessageFor(c => c.FirstName)
@Html.TextBoxFor(c => c.FirstName, new
<input />
@*@Html.ValidationMessageFor(c => c)
@Html.TextBoxFor(c => c, new
{
placeholder = "請輸入您的名字"
})
</p>
<p>
<label for="emailsignup" class="youmail">性別</label>
<br />
<br />
@Html.RadioButtonFor(c => c.Gender, Church.Net.Entity.Enumeration.Gender.Male)@Html.Label("弟兄")
@Html.RadioButtonFor(c => c.Gender, Church.Net.Entity.Enumeration.Gender.Female)@Html.Label("姊妹")
</p>
<p>
<label for="emailsignup" class="youmail">電話</label>
@Html.ValidationMessageFor(c => c.Phone)
@Html.TextBoxFor(c => c.Phone, new { placeholder = "請輸入您的聯繫電話" })
</p>
<p>
<label for="emailsignup" class="youmail">Email</label>
@Html.ValidationMessageFor(c => c.Email)
@Html.TextBoxFor(c => c.Email, new { placeholder = "請輸入您的聯繫Email" })
</p>
<p>
<label for="emailsignup" class="youmail">來訪原因</label>
@Html.ValidationMessageFor(c => c.Note)
@Html.TextBoxFor(c => c.Note, new { placeholder = "請輸入您的來訪原因" })
</p>
<p>
<label for="emailsignup" class="youmail">通信軟體 Id</label>
@Html.ValidationMessageFor(c => c.ComunityAppId)
@Html.TextBoxFor(c => c.ComunityAppId, new { placeholder = "請輸入您的通信軟體 Id ex:WeChat,Line" })
</p>
<p>
<label for="emailsignup" class="youmail">宗教信仰</label>
@Html.DropDownList("ReligionId", null, htmlAttributes: new { @class = "w-100 u-select-v2 u-shadow-v19 g-brd-none g-color-black g-color-primary--hover g-bg-white text-left g-rounded-30 g-pl-30 g-py-12" })
</p>
<p>
<label for="emailsignup" class="youmail">照片</label>
@Html.TextBox("AttachFile", "", new { @class = "form-control-file", type = "file", accept = "image/*;capture=camera" })
})*@
</p>
<p class="signin button">
<input type="submit" value="註冊" />
<input type="submit" value="Test" />
</p>
}

View File

@ -138,6 +138,10 @@ namespace Church.Net.DAL.EF
public DbSet<LineMessagingAccount> LineMessagingAccounts { get; set; }
public DbSet<Contribution> Contributions { get; set; }
public DbSet<HappinessCost> HappinessCosts { get; set; }
#endregion

View File

@ -204,6 +204,11 @@ namespace Church.Net.DAL.EFCoreDBF
{
throw new NotImplementedException();
}
public IEnumerable<T> GetAllById(IEnumerable<string> Ids)
{
throw new NotImplementedException();
}
}

View File

@ -65,6 +65,14 @@ namespace Church.Net.DAL.EFCoreDBF
return GetDbSet().AsNoTracking().Where(filter ?? (s => true)).ToList();
}
public virtual IQueryable<T> GetQuery(Func<T, bool> filter = null)
{
//var dbObjs = GetDbSet().ToArray();
//IEnumerable<T> list = GetDbSet().Where(filter ?? (s => true)).ToList();
return GetDbSet().AsNoTracking().Where(filter ?? (s => true)).AsQueryable<T>();
}
public virtual int Create(T entity)
{

View File

@ -241,10 +241,12 @@ namespace Church.Net.DAL.EFCoreDBF
DateTime localTime = ((DateTime)prop.GetValue(entity));
if (localTime.Kind != DateTimeKind.Utc)
{
//localTime= DateTime.SpecifyKind(localTime, DateTimeKind.Local);
localTime = new DateTime(localTime.Year, localTime.Month, localTime.Day,
localTime.Hour, localTime.Minute, localTime.Second, localTime.Millisecond);
localTime.Hour, localTime.Minute, localTime.Second,
localTime.Millisecond, DateTimeKind.Local);
}
var offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
var OutputTime = DateTime.SpecifyKind(localTime - offset, DateTimeKind.Utc);
DateTime utcTime = localTime.ToUniversalTime();
prop.SetValue(entity, utcTime, null);

View File

@ -31,6 +31,7 @@ namespace Church.Net.DAL.EFCoreDBF
int Delete(Func<T, bool> filter);
bool CheckExist(T obj);
IEnumerable<T> GetAllById(IEnumerable<string> Ids);
}
@ -55,5 +56,6 @@ namespace Church.Net.DAL.EFCoreDBF
int Delete(Func<T, bool> filter);
bool CheckExist(T obj);
IQueryable<T> GetQuery(Func<T, bool> filter = null);
}
}

View File

@ -0,0 +1,910 @@
// <auto-generated />
using System;
using Church.Net.DAL.EF;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Church.Net.DAL.EFCoreDBF.Migrations
{
[DbContext(typeof(ChurchNetContext))]
[Migration("20221012223219_AddCost")]
partial class AddCost
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Church.Net.Entity.AddressInfo", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("City")
.HasColumnType("text");
b.Property<string>("State")
.HasColumnType("text");
b.Property<string>("Zip")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("AddressInfos");
});
modelBuilder.Entity("Church.Net.Entity.AutoReplyItem", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Command")
.HasColumnType("text");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Description")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("AutoReplyItems");
});
modelBuilder.Entity("Church.Net.Entity.Career", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Name")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("Id");
b.ToTable("Careers");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("PastoralDomainId")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("PastoralDomainId");
b.ToTable("CellGroupRoutineEvents");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventAttendee", b =>
{
b.Property<string>("EventId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("Id")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<bool>("JoinPotluck")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("PotluckItem")
.HasColumnType("text");
b.HasKey("EventId", "Id");
b.ToTable("CellGroupRoutineEventAttendees");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventPrayer", b =>
{
b.Property<string>("EventId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("MemberId")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("Prayer")
.HasColumnType("text");
b.HasKey("EventId", "MemberId");
b.ToTable("CellGroupRoutineEventPrayers");
});
modelBuilder.Entity("Church.Net.Entity.Contribution", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("Contributor")
.HasColumnType("text");
b.Property<string>("GroupId")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("Contributions");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<string>("AvatarImage")
.HasColumnType("text");
b.Property<bool>("Baptized")
.HasColumnType("boolean");
b.Property<DateTime?>("Birthday")
.HasColumnType("timestamp with time zone");
b.Property<string>("CareerId")
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("ComunityAppId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("DateOfBaptized")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DateOfWalkIn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Email")
.HasColumnType("text");
b.Property<string>("FirstName")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<int>("Gender")
.HasColumnType("integer");
b.Property<string>("LastName")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<bool>("Married")
.HasColumnType("boolean");
b.Property<string>("Password")
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CareerId");
b.ToTable("FamilyMembers");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMemberOAuth", b =>
{
b.Property<string>("FamilyMemberId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("OAuthType")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("OAuthAccessToken")
.HasColumnType("text");
b.HasKey("FamilyMemberId", "OAuthType");
b.ToTable("FamilyMemberOAuths");
});
modelBuilder.Entity("Church.Net.Entity.HappinessBEST", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Email")
.HasColumnType("text");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("HappinessBESTs");
});
modelBuilder.Entity("Church.Net.Entity.HappinessCost", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Tasker")
.HasColumnType("text");
b.Property<string>("WeekId")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WeekId");
b.ToTable("HappinessCosts");
});
modelBuilder.Entity("Church.Net.Entity.HappinessTask", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Tasker")
.HasColumnType("text");
b.Property<int>("Type")
.HasColumnType("integer");
b.Property<string>("WeekId")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WeekId");
b.ToTable("HappinessTask");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("CityAndZipCode")
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<string>("InvitationText")
.HasColumnType("text");
b.Property<int>("SEQ")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("HappinessWeeks");
});
modelBuilder.Entity("Church.Net.Entity.LineMessagingAccount", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ChatToken")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<int>("Seq")
.HasColumnType("integer");
b.Property<int>("TotalUsage")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("LineMessagingAccounts");
});
modelBuilder.Entity("Church.Net.Entity.LogInfo", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("DetailMessage")
.HasColumnType("text");
b.Property<int>("Level")
.HasColumnType("integer");
b.Property<string>("Message")
.HasColumnType("text");
b.Property<string>("Source")
.HasColumnType("text");
b.Property<string>("StackTrace")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.Property<int>("TrackNo")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("TrackNo"));
b.Property<string>("Url")
.HasColumnType("text");
b.Property<string>("UserId")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("LogInfos");
});
modelBuilder.Entity("Church.Net.Entity.Messenger.LineMessageClient", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ClientId")
.HasColumnType("text");
b.Property<bool>("IsGroup")
.HasColumnType("boolean");
b.Property<bool>("IsManager")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("LineMessageClients");
});
modelBuilder.Entity("Church.Net.Entity.NewVisitor", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<DateTime?>("BirthDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("ComunityAppId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Email")
.HasMaxLength(150)
.HasColumnType("character varying(150)");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<int>("Gender")
.HasColumnType("integer");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Note")
.HasColumnType("text");
b.Property<string>("Phone")
.IsRequired()
.HasMaxLength(150)
.HasColumnType("character varying(150)");
b.Property<int?>("ReligionId")
.HasColumnType("integer");
b.Property<DateTime>("VisitingDate")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("ReligionId");
b.ToTable("NewVisitors");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Image1")
.HasColumnType("text");
b.Property<string>("Image2")
.HasColumnType("text");
b.Property<string>("Image3")
.HasColumnType("text");
b.Property<string>("Image4")
.HasColumnType("text");
b.Property<string>("Image5")
.HasColumnType("text");
b.Property<string>("LeaderMemberId")
.HasColumnType("text");
b.Property<string>("LineAccountId")
.HasColumnType("text");
b.Property<string>("LineGroupId")
.HasColumnType("text");
b.Property<string>("LogoImage")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("ServiceAddressId")
.HasColumnType("text");
b.Property<DateTime?>("ServiceTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Type")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("LeaderMemberId");
b.HasIndex("LineAccountId");
b.HasIndex("ServiceAddressId");
b.ToTable("PastoralDomains");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainAutoReplys", b =>
{
b.Property<string>("PastoralDomainCommunityAppId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("AutoReplyItemId")
.HasColumnType("text")
.HasColumnOrder(1);
b.HasKey("PastoralDomainCommunityAppId", "AutoReplyItemId");
b.HasIndex("AutoReplyItemId");
b.ToTable("PastoralDomainAutoReplys");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainMembers", b =>
{
b.Property<string>("PastoralDomainId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("FamilyMemberId")
.HasColumnType("text")
.HasColumnOrder(1);
b.HasKey("PastoralDomainId", "FamilyMemberId");
b.HasIndex("FamilyMemberId");
b.ToTable("PastoralDomainMembers");
});
modelBuilder.Entity("Church.Net.Entity.Religion", b =>
{
b.Property<int>("ReligionId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ReligionId"));
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("ReligionId");
b.ToTable("Religions");
});
modelBuilder.Entity("Church.Net.Entity.Vocabulary", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("DefinitionCh")
.IsRequired()
.HasColumnType("text");
b.Property<string>("DefinitionEn")
.IsRequired()
.HasColumnType("text");
b.Property<int>("FlashCardTimes")
.HasColumnType("integer");
b.Property<string>("ImagesUrl")
.HasColumnType("text");
b.Property<DateTime>("InsertDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("NounPlural")
.HasColumnType("text");
b.Property<int>("PartOfSpeech")
.HasColumnType("integer");
b.Property<bool>("PracticeApply")
.HasColumnType("boolean");
b.Property<DateTime>("PracticeDate")
.HasColumnType("timestamp with time zone");
b.Property<bool>("PracticeMemorized")
.HasColumnType("boolean");
b.Property<bool>("PracticeReview")
.HasColumnType("boolean");
b.Property<bool>("PracticeSelect")
.HasColumnType("boolean");
b.Property<string>("PracticeSentence")
.HasColumnType("text");
b.Property<int>("PracticeStage")
.HasColumnType("integer");
b.Property<bool>("PracticeVisualize")
.HasColumnType("boolean");
b.Property<string>("VerbParticiple")
.HasColumnType("text");
b.Property<string>("VerbPast")
.HasColumnType("text");
b.Property<string>("Word")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Vocabulary");
});
modelBuilder.Entity("Church.Net.Entity.WhoIsSpy", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Answer1Chs")
.HasColumnType("text");
b.Property<string>("Answer1Cht")
.HasColumnType("text");
b.Property<string>("Answer1En")
.HasColumnType("text");
b.Property<string>("Answer2Chs")
.HasColumnType("text");
b.Property<string>("Answer2Cht")
.HasColumnType("text");
b.Property<string>("Answer2En")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("WhoIsSpy");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "CellGroupInfo")
.WithMany()
.HasForeignKey("PastoralDomainId");
b.Navigation("CellGroupInfo");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventAttendee", b =>
{
b.HasOne("Church.Net.Entity.CellGroupRoutineEvent", "CellGroupRoutineEvent")
.WithMany("Attendees")
.HasForeignKey("EventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CellGroupRoutineEvent");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventPrayer", b =>
{
b.HasOne("Church.Net.Entity.CellGroupRoutineEvent", "CellGroupRoutineEvent")
.WithMany("Prayers")
.HasForeignKey("EventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CellGroupRoutineEvent");
});
modelBuilder.Entity("Church.Net.Entity.Contribution", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("Contributions")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.HasOne("Church.Net.Entity.Career", "Career")
.WithMany()
.HasForeignKey("CareerId");
b.Navigation("Career");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMemberOAuth", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", null)
.WithMany("OAuthInfos")
.HasForeignKey("FamilyMemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Church.Net.Entity.HappinessBEST", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("Bests")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.HappinessCost", b =>
{
b.HasOne("Church.Net.Entity.HappinessWeek", "HappinessWeek")
.WithMany("Costs")
.HasForeignKey("WeekId");
b.Navigation("HappinessWeek");
});
modelBuilder.Entity("Church.Net.Entity.HappinessTask", b =>
{
b.HasOne("Church.Net.Entity.HappinessWeek", "HappinessWeek")
.WithMany("Tasks")
.HasForeignKey("WeekId");
b.Navigation("HappinessWeek");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("HappinessWeeks")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.NewVisitor", b =>
{
b.HasOne("Church.Net.Entity.Religion", "Religion")
.WithMany()
.HasForeignKey("ReligionId");
b.Navigation("Religion");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", "Leader")
.WithMany()
.HasForeignKey("LeaderMemberId");
b.HasOne("Church.Net.Entity.LineMessagingAccount", "LineMessagingAccount")
.WithMany()
.HasForeignKey("LineAccountId");
b.HasOne("Church.Net.Entity.AddressInfo", "ServiceAddress")
.WithMany()
.HasForeignKey("ServiceAddressId");
b.Navigation("Leader");
b.Navigation("LineMessagingAccount");
b.Navigation("ServiceAddress");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainAutoReplys", b =>
{
b.HasOne("Church.Net.Entity.AutoReplyItem", "FamilyMember")
.WithMany("AutoReplyItemRelations")
.HasForeignKey("AutoReplyItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Church.Net.Entity.PastoralDomain", "PastoralDomain")
.WithMany("AutoReplyItemRelations")
.HasForeignKey("PastoralDomainCommunityAppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("FamilyMember");
b.Navigation("PastoralDomain");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainMembers", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", "FamilyMember")
.WithMany("PastoralDomains")
.HasForeignKey("FamilyMemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Church.Net.Entity.PastoralDomain", "PastoralDomain")
.WithMany("Members")
.HasForeignKey("PastoralDomainId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("FamilyMember");
b.Navigation("PastoralDomain");
});
modelBuilder.Entity("Church.Net.Entity.AutoReplyItem", b =>
{
b.Navigation("AutoReplyItemRelations");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.Navigation("Attendees");
b.Navigation("Prayers");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.Navigation("OAuthInfos");
b.Navigation("PastoralDomains");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.Navigation("Costs");
b.Navigation("Tasks");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.Navigation("AutoReplyItemRelations");
b.Navigation("Bests");
b.Navigation("Contributions");
b.Navigation("HappinessWeeks");
b.Navigation("Members");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,70 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Church.Net.DAL.EFCoreDBF.Migrations
{
public partial class AddCost : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Contributions",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
GroupId = table.Column<string>(type: "text", nullable: true),
Contributor = table.Column<string>(type: "text", nullable: true),
Amount = table.Column<decimal>(type: "numeric", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Contributions", x => x.Id);
table.ForeignKey(
name: "FK_Contributions_PastoralDomains_GroupId",
column: x => x.GroupId,
principalTable: "PastoralDomains",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "HappinessCosts",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
WeekId = table.Column<string>(type: "text", nullable: true),
Tasker = table.Column<string>(type: "text", nullable: true),
Content = table.Column<string>(type: "text", nullable: true),
Amount = table.Column<decimal>(type: "numeric", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_HappinessCosts", x => x.Id);
table.ForeignKey(
name: "FK_HappinessCosts_HappinessWeeks_WeekId",
column: x => x.WeekId,
principalTable: "HappinessWeeks",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Contributions_GroupId",
table: "Contributions",
column: "GroupId");
migrationBuilder.CreateIndex(
name: "IX_HappinessCosts_WeekId",
table: "HappinessCosts",
column: "WeekId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Contributions");
migrationBuilder.DropTable(
name: "HappinessCosts");
}
}
}

View File

@ -0,0 +1,916 @@
// <auto-generated />
using System;
using Church.Net.DAL.EF;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Church.Net.DAL.EFCoreDBF.Migrations
{
[DbContext(typeof(ChurchNetContext))]
[Migration("20221017002753_AddTimeToContribution")]
partial class AddTimeToContribution
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Church.Net.Entity.AddressInfo", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("City")
.HasColumnType("text");
b.Property<string>("State")
.HasColumnType("text");
b.Property<string>("Zip")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("AddressInfos");
});
modelBuilder.Entity("Church.Net.Entity.AutoReplyItem", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Command")
.HasColumnType("text");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Description")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("AutoReplyItems");
});
modelBuilder.Entity("Church.Net.Entity.Career", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Name")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("Id");
b.ToTable("Careers");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("PastoralDomainId")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("PastoralDomainId");
b.ToTable("CellGroupRoutineEvents");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventAttendee", b =>
{
b.Property<string>("EventId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("Id")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<bool>("JoinPotluck")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("PotluckItem")
.HasColumnType("text");
b.HasKey("EventId", "Id");
b.ToTable("CellGroupRoutineEventAttendees");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventPrayer", b =>
{
b.Property<string>("EventId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("MemberId")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("Prayer")
.HasColumnType("text");
b.HasKey("EventId", "MemberId");
b.ToTable("CellGroupRoutineEventPrayers");
});
modelBuilder.Entity("Church.Net.Entity.Contribution", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("Contributor")
.HasColumnType("text");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("Contributions");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<string>("AvatarImage")
.HasColumnType("text");
b.Property<bool>("Baptized")
.HasColumnType("boolean");
b.Property<DateTime?>("Birthday")
.HasColumnType("timestamp with time zone");
b.Property<string>("CareerId")
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("ComunityAppId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("DateOfBaptized")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DateOfWalkIn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Email")
.HasColumnType("text");
b.Property<string>("FirstName")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<int>("Gender")
.HasColumnType("integer");
b.Property<string>("LastName")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<bool>("Married")
.HasColumnType("boolean");
b.Property<string>("Password")
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CareerId");
b.ToTable("FamilyMembers");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMemberOAuth", b =>
{
b.Property<string>("FamilyMemberId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("OAuthType")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("OAuthAccessToken")
.HasColumnType("text");
b.HasKey("FamilyMemberId", "OAuthType");
b.ToTable("FamilyMemberOAuths");
});
modelBuilder.Entity("Church.Net.Entity.HappinessBEST", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Email")
.HasColumnType("text");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("HappinessBESTs");
});
modelBuilder.Entity("Church.Net.Entity.HappinessCost", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Tasker")
.HasColumnType("text");
b.Property<string>("WeekId")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WeekId");
b.ToTable("HappinessCosts");
});
modelBuilder.Entity("Church.Net.Entity.HappinessTask", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Tasker")
.HasColumnType("text");
b.Property<int>("Type")
.HasColumnType("integer");
b.Property<string>("WeekId")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WeekId");
b.ToTable("HappinessTask");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("CityAndZipCode")
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<string>("InvitationText")
.HasColumnType("text");
b.Property<int>("SEQ")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("HappinessWeeks");
});
modelBuilder.Entity("Church.Net.Entity.LineMessagingAccount", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ChatToken")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<int>("Seq")
.HasColumnType("integer");
b.Property<int>("TotalUsage")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("LineMessagingAccounts");
});
modelBuilder.Entity("Church.Net.Entity.LogInfo", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("DetailMessage")
.HasColumnType("text");
b.Property<int>("Level")
.HasColumnType("integer");
b.Property<string>("Message")
.HasColumnType("text");
b.Property<string>("Source")
.HasColumnType("text");
b.Property<string>("StackTrace")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.Property<int>("TrackNo")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("TrackNo"));
b.Property<string>("Url")
.HasColumnType("text");
b.Property<string>("UserId")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("LogInfos");
});
modelBuilder.Entity("Church.Net.Entity.Messenger.LineMessageClient", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ClientId")
.HasColumnType("text");
b.Property<bool>("IsGroup")
.HasColumnType("boolean");
b.Property<bool>("IsManager")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("LineMessageClients");
});
modelBuilder.Entity("Church.Net.Entity.NewVisitor", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<DateTime?>("BirthDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("ComunityAppId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Email")
.HasMaxLength(150)
.HasColumnType("character varying(150)");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<int>("Gender")
.HasColumnType("integer");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Note")
.HasColumnType("text");
b.Property<string>("Phone")
.IsRequired()
.HasMaxLength(150)
.HasColumnType("character varying(150)");
b.Property<int?>("ReligionId")
.HasColumnType("integer");
b.Property<DateTime>("VisitingDate")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("ReligionId");
b.ToTable("NewVisitors");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Image1")
.HasColumnType("text");
b.Property<string>("Image2")
.HasColumnType("text");
b.Property<string>("Image3")
.HasColumnType("text");
b.Property<string>("Image4")
.HasColumnType("text");
b.Property<string>("Image5")
.HasColumnType("text");
b.Property<string>("LeaderMemberId")
.HasColumnType("text");
b.Property<string>("LineAccountId")
.HasColumnType("text");
b.Property<string>("LineGroupId")
.HasColumnType("text");
b.Property<string>("LogoImage")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("ServiceAddressId")
.HasColumnType("text");
b.Property<DateTime?>("ServiceTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Type")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("LeaderMemberId");
b.HasIndex("LineAccountId");
b.HasIndex("ServiceAddressId");
b.ToTable("PastoralDomains");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainAutoReplys", b =>
{
b.Property<string>("PastoralDomainCommunityAppId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("AutoReplyItemId")
.HasColumnType("text")
.HasColumnOrder(1);
b.HasKey("PastoralDomainCommunityAppId", "AutoReplyItemId");
b.HasIndex("AutoReplyItemId");
b.ToTable("PastoralDomainAutoReplys");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainMembers", b =>
{
b.Property<string>("PastoralDomainId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("FamilyMemberId")
.HasColumnType("text")
.HasColumnOrder(1);
b.HasKey("PastoralDomainId", "FamilyMemberId");
b.HasIndex("FamilyMemberId");
b.ToTable("PastoralDomainMembers");
});
modelBuilder.Entity("Church.Net.Entity.Religion", b =>
{
b.Property<int>("ReligionId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ReligionId"));
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("ReligionId");
b.ToTable("Religions");
});
modelBuilder.Entity("Church.Net.Entity.Vocabulary", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("DefinitionCh")
.IsRequired()
.HasColumnType("text");
b.Property<string>("DefinitionEn")
.IsRequired()
.HasColumnType("text");
b.Property<int>("FlashCardTimes")
.HasColumnType("integer");
b.Property<string>("ImagesUrl")
.HasColumnType("text");
b.Property<DateTime>("InsertDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("NounPlural")
.HasColumnType("text");
b.Property<int>("PartOfSpeech")
.HasColumnType("integer");
b.Property<bool>("PracticeApply")
.HasColumnType("boolean");
b.Property<DateTime>("PracticeDate")
.HasColumnType("timestamp with time zone");
b.Property<bool>("PracticeMemorized")
.HasColumnType("boolean");
b.Property<bool>("PracticeReview")
.HasColumnType("boolean");
b.Property<bool>("PracticeSelect")
.HasColumnType("boolean");
b.Property<string>("PracticeSentence")
.HasColumnType("text");
b.Property<int>("PracticeStage")
.HasColumnType("integer");
b.Property<bool>("PracticeVisualize")
.HasColumnType("boolean");
b.Property<string>("VerbParticiple")
.HasColumnType("text");
b.Property<string>("VerbPast")
.HasColumnType("text");
b.Property<string>("Word")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Vocabulary");
});
modelBuilder.Entity("Church.Net.Entity.WhoIsSpy", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Answer1Chs")
.HasColumnType("text");
b.Property<string>("Answer1Cht")
.HasColumnType("text");
b.Property<string>("Answer1En")
.HasColumnType("text");
b.Property<string>("Answer2Chs")
.HasColumnType("text");
b.Property<string>("Answer2Cht")
.HasColumnType("text");
b.Property<string>("Answer2En")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("WhoIsSpy");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "CellGroupInfo")
.WithMany()
.HasForeignKey("PastoralDomainId");
b.Navigation("CellGroupInfo");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventAttendee", b =>
{
b.HasOne("Church.Net.Entity.CellGroupRoutineEvent", "CellGroupRoutineEvent")
.WithMany("Attendees")
.HasForeignKey("EventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CellGroupRoutineEvent");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventPrayer", b =>
{
b.HasOne("Church.Net.Entity.CellGroupRoutineEvent", "CellGroupRoutineEvent")
.WithMany("Prayers")
.HasForeignKey("EventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CellGroupRoutineEvent");
});
modelBuilder.Entity("Church.Net.Entity.Contribution", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("Contributions")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.HasOne("Church.Net.Entity.Career", "Career")
.WithMany()
.HasForeignKey("CareerId");
b.Navigation("Career");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMemberOAuth", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", null)
.WithMany("OAuthInfos")
.HasForeignKey("FamilyMemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Church.Net.Entity.HappinessBEST", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("Bests")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.HappinessCost", b =>
{
b.HasOne("Church.Net.Entity.HappinessWeek", "HappinessWeek")
.WithMany("Costs")
.HasForeignKey("WeekId");
b.Navigation("HappinessWeek");
});
modelBuilder.Entity("Church.Net.Entity.HappinessTask", b =>
{
b.HasOne("Church.Net.Entity.HappinessWeek", "HappinessWeek")
.WithMany("Tasks")
.HasForeignKey("WeekId");
b.Navigation("HappinessWeek");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("HappinessWeeks")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.NewVisitor", b =>
{
b.HasOne("Church.Net.Entity.Religion", "Religion")
.WithMany()
.HasForeignKey("ReligionId");
b.Navigation("Religion");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", "Leader")
.WithMany()
.HasForeignKey("LeaderMemberId");
b.HasOne("Church.Net.Entity.LineMessagingAccount", "LineMessagingAccount")
.WithMany()
.HasForeignKey("LineAccountId");
b.HasOne("Church.Net.Entity.AddressInfo", "ServiceAddress")
.WithMany()
.HasForeignKey("ServiceAddressId");
b.Navigation("Leader");
b.Navigation("LineMessagingAccount");
b.Navigation("ServiceAddress");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainAutoReplys", b =>
{
b.HasOne("Church.Net.Entity.AutoReplyItem", "FamilyMember")
.WithMany("AutoReplyItemRelations")
.HasForeignKey("AutoReplyItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Church.Net.Entity.PastoralDomain", "PastoralDomain")
.WithMany("AutoReplyItemRelations")
.HasForeignKey("PastoralDomainCommunityAppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("FamilyMember");
b.Navigation("PastoralDomain");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainMembers", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", "FamilyMember")
.WithMany("PastoralDomains")
.HasForeignKey("FamilyMemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Church.Net.Entity.PastoralDomain", "PastoralDomain")
.WithMany("Members")
.HasForeignKey("PastoralDomainId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("FamilyMember");
b.Navigation("PastoralDomain");
});
modelBuilder.Entity("Church.Net.Entity.AutoReplyItem", b =>
{
b.Navigation("AutoReplyItemRelations");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.Navigation("Attendees");
b.Navigation("Prayers");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.Navigation("OAuthInfos");
b.Navigation("PastoralDomains");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.Navigation("Costs");
b.Navigation("Tasks");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.Navigation("AutoReplyItemRelations");
b.Navigation("Bests");
b.Navigation("Contributions");
b.Navigation("HappinessWeeks");
b.Navigation("Members");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Church.Net.DAL.EFCoreDBF.Migrations
{
public partial class AddTimeToContribution : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Comment",
table: "Contributions",
type: "text",
nullable: true);
migrationBuilder.AddColumn<DateTime>(
name: "Time",
table: "Contributions",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Comment",
table: "Contributions");
migrationBuilder.DropColumn(
name: "Time",
table: "Contributions");
}
}
}

View File

@ -0,0 +1,919 @@
// <auto-generated />
using System;
using Church.Net.DAL.EF;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Church.Net.DAL.EFCoreDBF.Migrations
{
[DbContext(typeof(ChurchNetContext))]
[Migration("20230310201522_AddTimeZoneToGroup")]
partial class AddTimeZoneToGroup
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Church.Net.Entity.AddressInfo", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("City")
.HasColumnType("text");
b.Property<string>("State")
.HasColumnType("text");
b.Property<string>("Zip")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("AddressInfos");
});
modelBuilder.Entity("Church.Net.Entity.AutoReplyItem", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Command")
.HasColumnType("text");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Description")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("AutoReplyItems");
});
modelBuilder.Entity("Church.Net.Entity.Career", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Name")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("Id");
b.ToTable("Careers");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("PastoralDomainId")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("PastoralDomainId");
b.ToTable("CellGroupRoutineEvents");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventAttendee", b =>
{
b.Property<string>("EventId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("Id")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<bool>("JoinPotluck")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("PotluckItem")
.HasColumnType("text");
b.HasKey("EventId", "Id");
b.ToTable("CellGroupRoutineEventAttendees");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventPrayer", b =>
{
b.Property<string>("EventId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("MemberId")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("Prayer")
.HasColumnType("text");
b.HasKey("EventId", "MemberId");
b.ToTable("CellGroupRoutineEventPrayers");
});
modelBuilder.Entity("Church.Net.Entity.Contribution", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("Contributor")
.HasColumnType("text");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("Contributions");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<string>("AvatarImage")
.HasColumnType("text");
b.Property<bool>("Baptized")
.HasColumnType("boolean");
b.Property<DateTime?>("Birthday")
.HasColumnType("timestamp with time zone");
b.Property<string>("CareerId")
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("ComunityAppId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("DateOfBaptized")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DateOfWalkIn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Email")
.HasColumnType("text");
b.Property<string>("FirstName")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<int>("Gender")
.HasColumnType("integer");
b.Property<string>("LastName")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<bool>("Married")
.HasColumnType("boolean");
b.Property<string>("Password")
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CareerId");
b.ToTable("FamilyMembers");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMemberOAuth", b =>
{
b.Property<string>("FamilyMemberId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("OAuthType")
.HasColumnType("text")
.HasColumnOrder(1);
b.Property<string>("OAuthAccessToken")
.HasColumnType("text");
b.HasKey("FamilyMemberId", "OAuthType");
b.ToTable("FamilyMemberOAuths");
});
modelBuilder.Entity("Church.Net.Entity.HappinessBEST", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Email")
.HasColumnType("text");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("HappinessBESTs");
});
modelBuilder.Entity("Church.Net.Entity.HappinessCost", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Tasker")
.HasColumnType("text");
b.Property<string>("WeekId")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WeekId");
b.ToTable("HappinessCosts");
});
modelBuilder.Entity("Church.Net.Entity.HappinessTask", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Tasker")
.HasColumnType("text");
b.Property<int>("Type")
.HasColumnType("integer");
b.Property<string>("WeekId")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WeekId");
b.ToTable("HappinessTask");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasColumnType("text");
b.Property<string>("CityAndZipCode")
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<string>("InvitationText")
.HasColumnType("text");
b.Property<int>("SEQ")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("HappinessWeeks");
});
modelBuilder.Entity("Church.Net.Entity.LineMessagingAccount", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ChatToken")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<int>("Seq")
.HasColumnType("integer");
b.Property<int>("TotalUsage")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("LineMessagingAccounts");
});
modelBuilder.Entity("Church.Net.Entity.LogInfo", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("DetailMessage")
.HasColumnType("text");
b.Property<int>("Level")
.HasColumnType("integer");
b.Property<string>("Message")
.HasColumnType("text");
b.Property<string>("Source")
.HasColumnType("text");
b.Property<string>("StackTrace")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.Property<int>("TrackNo")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("TrackNo"));
b.Property<string>("Url")
.HasColumnType("text");
b.Property<string>("UserId")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("LogInfos");
});
modelBuilder.Entity("Church.Net.Entity.Messenger.LineMessageClient", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ClientId")
.HasColumnType("text");
b.Property<bool>("IsGroup")
.HasColumnType("boolean");
b.Property<bool>("IsManager")
.HasColumnType("boolean");
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("LineMessageClients");
});
modelBuilder.Entity("Church.Net.Entity.NewVisitor", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Address")
.HasMaxLength(500)
.HasColumnType("character varying(500)");
b.Property<DateTime?>("BirthDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("ComunityAppId")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Email")
.HasMaxLength(150)
.HasColumnType("character varying(150)");
b.Property<string>("FirstName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<int>("Gender")
.HasColumnType("integer");
b.Property<string>("LastName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Note")
.HasColumnType("text");
b.Property<string>("Phone")
.IsRequired()
.HasMaxLength(150)
.HasColumnType("character varying(150)");
b.Property<int?>("ReligionId")
.HasColumnType("integer");
b.Property<DateTime>("VisitingDate")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("ReligionId");
b.ToTable("NewVisitors");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<string>("Image1")
.HasColumnType("text");
b.Property<string>("Image2")
.HasColumnType("text");
b.Property<string>("Image3")
.HasColumnType("text");
b.Property<string>("Image4")
.HasColumnType("text");
b.Property<string>("Image5")
.HasColumnType("text");
b.Property<string>("LeaderMemberId")
.HasColumnType("text");
b.Property<string>("LineAccountId")
.HasColumnType("text");
b.Property<string>("LineGroupId")
.HasColumnType("text");
b.Property<string>("LogoImage")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("ServiceAddressId")
.HasColumnType("text");
b.Property<DateTime?>("ServiceTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("TimeZone")
.HasColumnType("text");
b.Property<int>("Type")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("LeaderMemberId");
b.HasIndex("LineAccountId");
b.HasIndex("ServiceAddressId");
b.ToTable("PastoralDomains");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainAutoReplys", b =>
{
b.Property<string>("PastoralDomainCommunityAppId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("AutoReplyItemId")
.HasColumnType("text")
.HasColumnOrder(1);
b.HasKey("PastoralDomainCommunityAppId", "AutoReplyItemId");
b.HasIndex("AutoReplyItemId");
b.ToTable("PastoralDomainAutoReplys");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainMembers", b =>
{
b.Property<string>("PastoralDomainId")
.HasColumnType("text")
.HasColumnOrder(0);
b.Property<string>("FamilyMemberId")
.HasColumnType("text")
.HasColumnOrder(1);
b.HasKey("PastoralDomainId", "FamilyMemberId");
b.HasIndex("FamilyMemberId");
b.ToTable("PastoralDomainMembers");
});
modelBuilder.Entity("Church.Net.Entity.Religion", b =>
{
b.Property<int>("ReligionId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("ReligionId"));
b.Property<string>("Name")
.HasColumnType("text");
b.HasKey("ReligionId");
b.ToTable("Religions");
});
modelBuilder.Entity("Church.Net.Entity.Vocabulary", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("DefinitionCh")
.IsRequired()
.HasColumnType("text");
b.Property<string>("DefinitionEn")
.IsRequired()
.HasColumnType("text");
b.Property<int>("FlashCardTimes")
.HasColumnType("integer");
b.Property<string>("ImagesUrl")
.HasColumnType("text");
b.Property<DateTime>("InsertDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("NounPlural")
.HasColumnType("text");
b.Property<int>("PartOfSpeech")
.HasColumnType("integer");
b.Property<bool>("PracticeApply")
.HasColumnType("boolean");
b.Property<DateTime>("PracticeDate")
.HasColumnType("timestamp with time zone");
b.Property<bool>("PracticeMemorized")
.HasColumnType("boolean");
b.Property<bool>("PracticeReview")
.HasColumnType("boolean");
b.Property<bool>("PracticeSelect")
.HasColumnType("boolean");
b.Property<string>("PracticeSentence")
.HasColumnType("text");
b.Property<int>("PracticeStage")
.HasColumnType("integer");
b.Property<bool>("PracticeVisualize")
.HasColumnType("boolean");
b.Property<string>("VerbParticiple")
.HasColumnType("text");
b.Property<string>("VerbPast")
.HasColumnType("text");
b.Property<string>("Word")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Vocabulary");
});
modelBuilder.Entity("Church.Net.Entity.WhoIsSpy", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Answer1Chs")
.HasColumnType("text");
b.Property<string>("Answer1Cht")
.HasColumnType("text");
b.Property<string>("Answer1En")
.HasColumnType("text");
b.Property<string>("Answer2Chs")
.HasColumnType("text");
b.Property<string>("Answer2Cht")
.HasColumnType("text");
b.Property<string>("Answer2En")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("WhoIsSpy");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "CellGroupInfo")
.WithMany()
.HasForeignKey("PastoralDomainId");
b.Navigation("CellGroupInfo");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventAttendee", b =>
{
b.HasOne("Church.Net.Entity.CellGroupRoutineEvent", "CellGroupRoutineEvent")
.WithMany("Attendees")
.HasForeignKey("EventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CellGroupRoutineEvent");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEventPrayer", b =>
{
b.HasOne("Church.Net.Entity.CellGroupRoutineEvent", "CellGroupRoutineEvent")
.WithMany("Prayers")
.HasForeignKey("EventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CellGroupRoutineEvent");
});
modelBuilder.Entity("Church.Net.Entity.Contribution", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("Contributions")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.HasOne("Church.Net.Entity.Career", "Career")
.WithMany()
.HasForeignKey("CareerId");
b.Navigation("Career");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMemberOAuth", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", null)
.WithMany("OAuthInfos")
.HasForeignKey("FamilyMemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Church.Net.Entity.HappinessBEST", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("Bests")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.HappinessCost", b =>
{
b.HasOne("Church.Net.Entity.HappinessWeek", "HappinessWeek")
.WithMany("Costs")
.HasForeignKey("WeekId");
b.Navigation("HappinessWeek");
});
modelBuilder.Entity("Church.Net.Entity.HappinessTask", b =>
{
b.HasOne("Church.Net.Entity.HappinessWeek", "HappinessWeek")
.WithMany("Tasks")
.HasForeignKey("WeekId");
b.Navigation("HappinessWeek");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("HappinessWeeks")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.NewVisitor", b =>
{
b.HasOne("Church.Net.Entity.Religion", "Religion")
.WithMany()
.HasForeignKey("ReligionId");
b.Navigation("Religion");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", "Leader")
.WithMany()
.HasForeignKey("LeaderMemberId");
b.HasOne("Church.Net.Entity.LineMessagingAccount", "LineMessagingAccount")
.WithMany()
.HasForeignKey("LineAccountId");
b.HasOne("Church.Net.Entity.AddressInfo", "ServiceAddress")
.WithMany()
.HasForeignKey("ServiceAddressId");
b.Navigation("Leader");
b.Navigation("LineMessagingAccount");
b.Navigation("ServiceAddress");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainAutoReplys", b =>
{
b.HasOne("Church.Net.Entity.AutoReplyItem", "FamilyMember")
.WithMany("AutoReplyItemRelations")
.HasForeignKey("AutoReplyItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Church.Net.Entity.PastoralDomain", "PastoralDomain")
.WithMany("AutoReplyItemRelations")
.HasForeignKey("PastoralDomainCommunityAppId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("FamilyMember");
b.Navigation("PastoralDomain");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomainMembers", b =>
{
b.HasOne("Church.Net.Entity.FamilyMember", "FamilyMember")
.WithMany("PastoralDomains")
.HasForeignKey("FamilyMemberId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Church.Net.Entity.PastoralDomain", "PastoralDomain")
.WithMany("Members")
.HasForeignKey("PastoralDomainId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("FamilyMember");
b.Navigation("PastoralDomain");
});
modelBuilder.Entity("Church.Net.Entity.AutoReplyItem", b =>
{
b.Navigation("AutoReplyItemRelations");
});
modelBuilder.Entity("Church.Net.Entity.CellGroupRoutineEvent", b =>
{
b.Navigation("Attendees");
b.Navigation("Prayers");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.Navigation("OAuthInfos");
b.Navigation("PastoralDomains");
});
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.Navigation("Costs");
b.Navigation("Tasks");
});
modelBuilder.Entity("Church.Net.Entity.PastoralDomain", b =>
{
b.Navigation("AutoReplyItemRelations");
b.Navigation("Bests");
b.Navigation("Contributions");
b.Navigation("HappinessWeeks");
b.Navigation("Members");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,25 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Church.Net.DAL.EFCoreDBF.Migrations
{
public partial class AddTimeZoneToGroup : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "TimeZone",
table: "PastoralDomains",
type: "text",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "TimeZone",
table: "PastoralDomains");
}
}
}

View File

@ -146,6 +146,33 @@ namespace Church.Net.DAL.EFCoreDBF.Migrations
b.ToTable("CellGroupRoutineEventPrayers");
});
modelBuilder.Entity("Church.Net.Entity.Contribution", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("Comment")
.HasColumnType("text");
b.Property<string>("Contributor")
.HasColumnType("text");
b.Property<string>("GroupId")
.HasColumnType("text");
b.Property<DateTime>("Time")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("GroupId");
b.ToTable("Contributions");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.Property<string>("Id")
@ -253,6 +280,30 @@ namespace Church.Net.DAL.EFCoreDBF.Migrations
b.ToTable("HappinessBESTs");
});
modelBuilder.Entity("Church.Net.Entity.HappinessCost", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("Tasker")
.HasColumnType("text");
b.Property<string>("WeekId")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WeekId");
b.ToTable("HappinessCosts");
});
modelBuilder.Entity("Church.Net.Entity.HappinessTask", b =>
{
b.Property<string>("Id")
@ -492,6 +543,9 @@ namespace Church.Net.DAL.EFCoreDBF.Migrations
b.Property<DateTime?>("ServiceTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("TimeZone")
.HasColumnType("text");
b.Property<int>("Type")
.HasColumnType("integer");
@ -688,6 +742,15 @@ namespace Church.Net.DAL.EFCoreDBF.Migrations
b.Navigation("CellGroupRoutineEvent");
});
modelBuilder.Entity("Church.Net.Entity.Contribution", b =>
{
b.HasOne("Church.Net.Entity.PastoralDomain", "HappinessGroup")
.WithMany("Contributions")
.HasForeignKey("GroupId");
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.FamilyMember", b =>
{
b.HasOne("Church.Net.Entity.Career", "Career")
@ -715,6 +778,15 @@ namespace Church.Net.DAL.EFCoreDBF.Migrations
b.Navigation("HappinessGroup");
});
modelBuilder.Entity("Church.Net.Entity.HappinessCost", b =>
{
b.HasOne("Church.Net.Entity.HappinessWeek", "HappinessWeek")
.WithMany("Costs")
.HasForeignKey("WeekId");
b.Navigation("HappinessWeek");
});
modelBuilder.Entity("Church.Net.Entity.HappinessTask", b =>
{
b.HasOne("Church.Net.Entity.HappinessWeek", "HappinessWeek")
@ -822,6 +894,8 @@ namespace Church.Net.DAL.EFCoreDBF.Migrations
modelBuilder.Entity("Church.Net.Entity.HappinessWeek", b =>
{
b.Navigation("Costs");
b.Navigation("Tasks");
});
@ -831,6 +905,8 @@ namespace Church.Net.DAL.EFCoreDBF.Migrations
b.Navigation("Bests");
b.Navigation("Contributions");
b.Navigation("HappinessWeeks");
b.Navigation("Members");

View File

@ -0,0 +1,23 @@
using Church.Net.Entity.Interface;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.ComponentModel;
namespace Church.Net.Entity
{
public class Contribution : IEntity
{
[ForeignKey("HappinessGroup")]
public string GroupId { get; set; }
public PastoralDomain HappinessGroup { get; set; }
[Key]
public string Id { get; set; }
public string Contributor { get; set; }
public decimal Amount { get; set; }
public string Comment { get; set; }
public DateTime Time { get; set; }
}
}

View File

@ -29,6 +29,7 @@ namespace Church.Net.Entity
[NotMapped]
public string Topic { get; set; }
public virtual ICollection<HappinessTask> Tasks { get; set; }
public virtual ICollection<HappinessCost> Costs { get; set; }
public string Comment { get; set; }
}
@ -58,4 +59,18 @@ namespace Church.Net.Entity
public string Tasker { get; set; }
public string Content { get; set; }
}
public class HappinessCost : IEntity
{
[ForeignKey("HappinessWeek")]
public string WeekId { get; set; }
public HappinessWeek HappinessWeek { get; set; }
[Key]
public string Id { get; set; }
public string Tasker { get; set; }
public string Content { get; set; }
public decimal Amount { get; set; }
}
}

View File

@ -16,7 +16,7 @@ namespace Church.Net.Entity
HappinessGroup,
CellGroupCoworker,
ChurchCoworker,
Person = 99
Administrator = 99
}
public class PastoralDomain : IEntity, IMessengerClient
{
@ -57,8 +57,10 @@ namespace Church.Net.Entity
public DomainType Type { get; set; }
public DateTime? ServiceTime { get; set; }
public string TimeZone { get; set; }
public virtual ICollection<HappinessBEST> Bests { get; set; }
public virtual ICollection<HappinessWeek> HappinessWeeks { get; set; }
public virtual ICollection<Contribution> Contributions { get; set; }
[JsonIgnore]
public virtual ICollection<PastoralDomainMembers> Members { get; set; }

View File

@ -16,13 +16,32 @@ namespace Church.Net.Utility
int daysToAdd = ((int)day - (int)start.DayOfWeek + 7) % 7;
return start.AddDays(daysToAdd);
}
public static DateTime Now()
public static DateTime Now(string timeZoneCode=null)
{
TimeZoneInfo timeZone;
if (null== timeZoneCode)
{
timeZone = pacificZone;
}
else
{
timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneCode);
}
return TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, pacificZone);
}
public static DateTime Today()
public static DateTime Today(string timeZoneCode = null)
{
return Now().Date;
return Now(timeZoneCode).Date;
}
public static DateTime ToUtc(this DateTime time,string timeZoneCode)
{
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneCode);
return TimeZoneInfo.ConvertTimeToUtc(time, timeZone);
}
public static DateTime ToLocal(this DateTime time, string timeZoneCode)
{
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneCode);
return TimeZoneInfo.ConvertTimeFromUtc(time, timeZone);
}
}
}

View File

@ -24,6 +24,9 @@ namespace Church.Net.Utility
{
byte[] data = Convert.FromBase64String(token);
DateTime when = DateTime.FromBinary(BitConverter.ToInt64(data, 0));
#if DEBUG
when = DateTime.Today.AddDays(1);
#endif
if (when >= DateTime.Now)
{
string userId = Encoding.ASCII.GetString(data.Skip(8).ToArray());

View File

@ -118,6 +118,23 @@ namespace LineMessaging
});
}
public async Task PushJsonMessage(string to, string jsonMessage)
{
if (to == null)
{
throw new ArgumentNullException(nameof(to));
}
if (jsonMessage == null)
{
throw new ArgumentNullException(nameof(jsonMessage));
}
await Post(LineMessagePushApiPath,
"{\r\n \"to\": \""+ to + "\",\r\n \"messages\":["+ jsonMessage + "]\r\n}"
);
}
public async Task MulticastMessage(LineMulticastMessage multicastMessage)
{
if (multicastMessage == null)

View File

@ -156,7 +156,15 @@ namespace LineMessaging
{
if (body != null)
{
string jsonContent = JsonConvert.SerializeObject(body, serializerSettings);
string jsonContent;
if (body is string)
{
jsonContent = body.ToString();
}
else
{
jsonContent = JsonConvert.SerializeObject(body, serializerSettings);
}
message.Content = new StringContent(jsonContent);
message.Content.Headers.ContentType = MediaTypeJson;

View File

@ -46,8 +46,28 @@ namespace LineMessaging
public ActionType Type => ActionType.Uri;
[JsonProperty("label")]
public string Label { get; set; }
private string _uri;
[JsonProperty("uri")]
public string Uri { get; set; }
public string Uri
{
get { return _uri; }
set {
if (value.IndexOf("?") == -1)
{
value += "?openExternalBrowser=1";
}
else
{
value += "&openExternalBrowser=1";
}
_uri = value;
}
}
}
public class DatetimepickerAction : ILineAction

View File

@ -3,6 +3,7 @@ using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
@ -108,11 +109,16 @@ namespace LineMessaging
}
public class LineFlexButton : ILineFlexObject
{
public LineFlexButton()
{
Height = FlexObjectSize.md;
}
public FlexObjectType Type => FlexObjectType.Button;
[JsonRequired]
public ILineAction Action { get; set; }
public FlexObjectButtonStype Style { get; set; }
//public FlexObjectSize Size { get; set; }
public FlexObjectSize Height { get; set; }
}
public class LineFlexImage : ILineFlexObject
{

View File

@ -41,12 +41,12 @@ namespace WebAPI.Controllers
}
[HttpPost]
public virtual async Task<string> CreateOrUpdate([FromBody] T entity)
public virtual async Task<T> CreateOrUpdate([FromBody] T entity)
{
return await Task.Run(() =>
{
logic.CreateOrUpdate(entity, out string id);
return id;
return entity;
});
}
[HttpPost]
@ -109,11 +109,12 @@ namespace WebAPI.Controllers
}
[HttpPost]
public virtual async Task<int> CreateOrUpdate([FromBody] T entity)
public virtual async Task<T> CreateOrUpdate([FromBody] T entity)
{
return await Task.Run(() =>
{
return logic.CreateOrUpdate(entity);
logic.CreateOrUpdate(entity);
return entity;
});
}
[HttpPost]

View File

@ -96,7 +96,7 @@ namespace WebAPI.Controllers
[HttpPost]
public int UpdateBestWeek(HappinessWeek week)
{
return weekLogic.CreateOrUpdate(week,out string id);
return cellGroupLogic.UpdateWeekInfo(week);
}
private Font arialFont;

View File

@ -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)
{
}
}
}

View File

@ -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)
{
}
}
}

View File

@ -24,6 +24,7 @@ using Jint.Native;
using WebAPI.Services.Interfaces;
using Church.Net.DAL.EFCoreDBF.Migrations;
using Church.Net.DAL.EFCoreDBF;
using WebAPI.Logics;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace WebAPI.Controllers
@ -36,16 +37,19 @@ namespace WebAPI.Controllers
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
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>
@ -109,11 +113,11 @@ namespace WebAPI.Controllers
}
//[HttpGet]
//public Task PushCommandMessage(string groupToken, string command)
//{
// return lineAutoBotService.PushCommandMessage(EnumHelper.GetEnumValueFromDescription<LineGroup>(groupToken), "#" + command);
//}
[HttpGet]
public Task PushCommandMessage(string groupId, string command)
{
return lineAutoBotService.PushCommandMessage(pastoralDomainLogic.GetById(groupId), "#" + command);
}
}

View File

@ -2,28 +2,39 @@
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;
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)
@ -43,5 +54,29 @@ namespace WebAPI.Controllers
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;
}
}
}

View File

@ -113,7 +113,7 @@ namespace WebAPI.Controllers
var templateMessage = new LineTemplateMessage<ButtonTemplateObject>();
var addPrayerBtn = new UriAction()
{
Uri = "https://happiness.tours/CellGroup/prayer?openExternalBrowser=1",
Uri = "https://happiness.tours/CellGroup/prayer",
Label = "Prayer"
};
templateMessage.AltText = "代禱事項";

View File

@ -0,0 +1,23 @@
using Church.Net.DAL.EFCoreDBF;
using Church.Net.Entity;
using WebAPI.Logics.Core;
using WebAPI.Logics.Interface;
namespace WebAPI.Logics
{
public class MemberLogic : LogicBase<FamilyMember>, ICrudLogic<FamilyMember>
{
public MemberLogic(
LogicService logicService,
ICrudDAL<FamilyMember> crudDAL
) : base(logicService, crudDAL)
{
}
public override void BeforeUpdate(FamilyMember entity)
{
entity.Password = crudDAL.First(m => m.Id == entity.Id).Password;
}
}
}

View File

@ -17,37 +17,40 @@ namespace WebAPI.Logics
string[] weekTopics = new string[] { "真幸福", "真相大白", "萬世巨星", "幸福連線", "當上帝來敲門", "十字架的勝利", "釋放與自由", "幸福的教會" };
private readonly IServiceScopeFactory serviceScopeFactory;
private readonly ICrudDAL<CellGroupRoutineEvent> eventCrudDAL;
private readonly ICombinedKeyCrudDAL<CellGroupRoutineEventAttendee> attendeeCrudDAL;
private readonly ICrudDAL<FamilyMember> memberCrudDAL;
private readonly ICrudDAL<AddressInfo> addressCrudDAL;
private readonly ICombinedKeyCrudDAL<PastoralDomainMembers> pastoralDomainMemberDAL;
private readonly ICrudDAL<HappinessWeek> weekCrudDAL;
private readonly ICrudDAL<HappinessBEST> bestCrudDAL;
private readonly ICrudDAL<HappinessTask> weekTaskCrudDAL;
private readonly ICrudDAL<HappinessCost> happinessCostCrudDAL;
private readonly ICrudDAL<Contribution> contributionCrudDAL;
public PastoralDomainLogic(
IServiceScopeFactory serviceScopeFactory,
LogicService logicService,
ICrudDAL<PastoralDomain> crudDAL,
ICrudDAL<CellGroupRoutineEvent> eventCrudDAL,
ICombinedKeyCrudDAL<CellGroupRoutineEventAttendee> attendeeCrudDAL,
ICrudDAL<FamilyMember> memberCrudDAL,
ICrudDAL<AddressInfo> addressCrudDAL,
ICombinedKeyCrudDAL<PastoralDomainMembers> pastoralDomainMemberDAL,
ICrudDAL<HappinessWeek> weekCrudDAL,
ICrudDAL<HappinessBEST> bestCrudDAL,
ICrudDAL<HappinessTask> weekTaskCrudDAL
ICrudDAL<HappinessTask> weekTaskCrudDAL,
ICrudDAL<Contribution> contributionCrudDALL,
ICrudDAL<HappinessCost> happinessCostCrudDAL
) : base(logicService, crudDAL)
{
this.serviceScopeFactory = serviceScopeFactory;
this.eventCrudDAL = eventCrudDAL;
this.attendeeCrudDAL = attendeeCrudDAL;
this.memberCrudDAL = memberCrudDAL;
this.addressCrudDAL = addressCrudDAL;
this.pastoralDomainMemberDAL = pastoralDomainMemberDAL;
this.weekCrudDAL = weekCrudDAL;
this.bestCrudDAL = bestCrudDAL;
this.weekTaskCrudDAL = weekTaskCrudDAL;
this.happinessCostCrudDAL = happinessCostCrudDAL;
this.contributionCrudDAL = contributionCrudDALL;
}
@ -57,20 +60,26 @@ namespace WebAPI.Logics
public override IEnumerable<PastoralDomain> GetAll(Func<PastoralDomain, bool> filter = null)
{
var list = base.GetAll(filter);
foreach (var item in list)
foreach (var group in list)
{
if (!string.IsNullOrEmpty(item.ServiceAddressId))
if (!string.IsNullOrEmpty(group.ServiceAddressId))
{
item.ServiceAddress = addressCrudDAL.GetById(item.ServiceAddressId);
group.ServiceAddress = addressCrudDAL.GetById(group.ServiceAddressId);
}
else
{
item.ServiceAddress = new AddressInfo();
group.ServiceAddress = new AddressInfo();
}
if (item.Type == DomainType.HappinessGroup)
if (group.Type == DomainType.HappinessGroup)
{
GetHappinessGroupInfo(item);
GetHappinessGroupInfo(group);
}
group.FamilyMembers =
memberCrudDAL.GetAllById(
pastoralDomainMemberDAL.GetAll(d => d.PastoralDomainId == group.Id).Select(d => d.FamilyMemberId).ToList()
).ToList();
group.Contributions = contributionCrudDAL.GetAll(d => d.GroupId == group.Id).ToList();
}
return list;
}
@ -91,31 +100,42 @@ namespace WebAPI.Logics
public CellGroupRoutineEvent GetComingEvent(string domainId = null)
{
PastoralDomain cellGroup;
if (domainId == null)
{
var cellGroup = GetCurrentUserCellGroup();
cellGroup = GetCurrentUserCellGroup();
if (cellGroup != null)
{
domainId = cellGroup.Id;
var _event = eventCrudDAL.GetDbSet().OrderByDescending(e => e.Time)
.Include(e => e.Attendees).Include(e => e.Prayers)
.Where(e => e.PastoralDomainId == domainId).FirstOrDefault();
return _event;
//var _event = eventCrudDAL.GetDbSet().OrderByDescending(e => e.Time)
// .Include(e => e.Attendees).Include(e => e.Prayers)
// .Where(e => e.PastoralDomainId == domainId).FirstOrDefault();
//return _event;
}
}
else
{
cellGroup= crudDAL.GetById(domainId);
}
if (domainId != null)
{
var _event = eventCrudDAL.GetDbSet().Where(e => e.PastoralDomainId == domainId && e.Time >= DateTime.UtcNow)
.Include(e => e.Attendees).Include(e => e.Prayers).FirstOrDefault();
if (_event == null)
{
var serviceLocalTime = cellGroup.ServiceTime.Value.ToUniversalTime().ToLocal(cellGroup.TimeZone);
var serviceWeekDay = serviceLocalTime.DayOfWeek;
var nextServiceTime = DateTimeHelper.GetNextWeekday(DateTimeHelper.Today(cellGroup.TimeZone), DayOfWeek.Friday)
.AddHours(serviceLocalTime.Hour).AddMinutes(serviceLocalTime.Minute);
_event = new CellGroupRoutineEvent()
{
Id = Format.Get33BaseGuid(),
Time = DateTimeHelper.GetNextWeekday(DateTime.Today, DayOfWeek.Friday).AddHours(19).AddMinutes(30),
Time = nextServiceTime.ToUtc(cellGroup.TimeZone),
Address = "1881 Forest Dr., Azusa, CA 91702",
Attendees = new List<CellGroupRoutineEventAttendee>(),
PastoralDomainId = domainId
@ -167,7 +187,17 @@ namespace WebAPI.Logics
if (!string.IsNullOrWhiteSpace(logicService.CurrentUserId))
{
var ids = pastoralDomainMemberDAL.GetAll(p => p.FamilyMemberId == logicService.CurrentUserId).Select(p => p.PastoralDomainId);
return crudDAL.GetAll(p => ids.Contains(p.Id));
var list = crudDAL.GetAll(p => ids.Contains(p.Id));
foreach (var group in list)
{
if (group.Type == DomainType.HappinessGroup)
{
GetHappinessGroupInfo(group);
}
group.Contributions = contributionCrudDAL.GetAll(d => d.GroupId == group.Id).ToList();
}
return list;
}
return null;
}
@ -231,10 +261,11 @@ namespace WebAPI.Logics
foreach (var week in group.HappinessWeeks)
{
week.Topic = weekTopics[week.SEQ - 1];
week.Tasks = weekTaskCrudDAL.GetAll(t => t.WeekId == week.Id).ToList();
week.Tasks = weekTaskCrudDAL.GetAll(t => t.WeekId == week.Id).OrderBy(t => t.Type).ToList();
week.Costs = happinessCostCrudDAL.GetAll(t => t.WeekId == week.Id).ToList();
}
group.Bests = bestCrudDAL.GetAll(b => b.GroupId == group.Id).ToList();
group.Bests = bestCrudDAL.GetAll(b => b.GroupId == group.Id).OrderBy(b => b.Name).ToList();
}
}
}

View File

@ -32,6 +32,7 @@ namespace WebAPI.Services.AutoReplyCommands
public IEnumerable<string> Commands => COMMANDS;
public IEnumerable<DomainType> SupportGroups => GROUPS;
public string ReplyTextMessage => null;
public string ReplyJsonMessage => null;
public IEnumerable<ILineMessage> LineMessage
{
@ -178,7 +179,7 @@ namespace WebAPI.Services.AutoReplyCommands
{
Action = new UriAction()
{
Uri = "https://happiness.tours/CellGroup/dinner?openExternalBrowser=1",
Uri = $"https://happiness.tours/myapp/dinner/{pastoralDomain.Id}",
Label = "我的菜單"
}
}

View File

@ -28,6 +28,8 @@ namespace WebAPI.Services.AutoReplyCommands
public IEnumerable<DomainType> SupportGroups => GROUPS;
public IEnumerable<ILineMessage> LineMessage => null;
public string ReplyJsonMessage => null;
public void Initialize(PastoralDomain pastoralDomain = null)
{
this.pastoralDomain = pastoralDomain;

View File

@ -77,6 +77,7 @@ namespace WebAPI.Services.AutoReplyCommands
public IEnumerable<string> Commands => COMMANDS;
public IEnumerable<DomainType> SupportGroups => GROUPS;
public string ReplyTextMessage => null;
public string ReplyJsonMessage => null;
public IEnumerable<ILineMessage> LineMessage
{
get
@ -215,7 +216,7 @@ namespace WebAPI.Services.AutoReplyCommands
{
Action = new UriAction()
{
Uri = "https://happiness.tours/CellGroup/prayer?openExternalBrowser=1",
Uri = $"https://happiness.tours/myapp/prayer/{pastoralDomain.Id}",
Label = "我的代禱事項"
}
}
@ -236,6 +237,7 @@ namespace WebAPI.Services.AutoReplyCommands
}
public bool Enabled(PastoralDomain pastoralDomain = null, string command = null)
{
this.pastoralDomain = pastoralDomain;
return COMMANDS.Any(c => c.IndexOf(command) == 0);
}
}

View File

@ -24,11 +24,13 @@ namespace WebAPI.Services.AutoReplyCommands
public string ReplyTextMessage => MESSAGES;
public IEnumerable<ILineMessage> LineMessage => null;
public string ReplyJsonMessage => null;
IEnumerable<DomainType> IAutoReplyCommand.SupportGroups => GROUPS;
public bool Enabled(PastoralDomain pastoralDomain = null, string command = null)
{
//this.pastoralDomain = pastoralDomain;
return COMMANDS.Any(c => c.IndexOf(command, StringComparison.OrdinalIgnoreCase) == 0);
}

View File

@ -32,6 +32,7 @@ namespace WebAPI.Services.AutoReplyCommands
public IEnumerable<string> Commands => COMMANDS;
public IEnumerable<DomainType> SupportGroups => GROUPS;
public string ReplyTextMessage => null;
public string ReplyJsonMessage => null;
public IEnumerable<ILineMessage> LineMessage
{
@ -83,7 +84,8 @@ namespace WebAPI.Services.AutoReplyCommands
Text = $"親愛的 {best.Name},想邀請你來參加這周的幸福聚會唷! 這是這周的邀請函!\n\nhttps://happiness.tours/invitation/{best.Id}",
Label = best.Name,
//InputOption= "openKeyboard"
}
},
Height = FlexObjectSize.sm,
}
);

View File

@ -28,15 +28,205 @@ namespace WebAPI.Services.AutoReplyCommands
};
private readonly PastoralDomainLogic logic;
public string Description => "顯示幸福小組分工表 #代表周數";
public string Description => "顯示幸福小組分工表 #代表周數 9顯示所有分工";
public IEnumerable<string> Commands => COMMANDS;
public IEnumerable<DomainType> SupportGroups => GROUPS;
public string ReplyTextMessage => null;
public string ReplyJsonMessage => jsonMessage;
private string jsonMessage;
private IEnumerable<ILineMessage> lineMessages;
public IEnumerable<ILineMessage> LineMessage => lineMessages;
public IEnumerable<ILineMessage> LineMessage
public void Initialize(PastoralDomain pastoralDomain = null)
{
get
this.pastoralDomain = pastoralDomain;
}
private int weekSeq = 0;
private HappinessWeek week = null;
public bool Enabled(PastoralDomain pastoralDomain = null, string command = null)
{
if (pastoralDomain != null && command.IndexOf("分工")>-1)
{
this.pastoralDomain = pastoralDomain;
command = command.Replace("分工", "");
if (command.Length > 0)
{
weekSeq = int.Parse(command);
}
logic.GetHappinessGroupInfo(pastoralDomain);
if (weekSeq > 0)
{
week = pastoralDomain.HappinessWeeks.Where(w => w.SEQ == weekSeq).FirstOrDefault();
}
else
{
week = pastoralDomain.HappinessWeeks.Where(w => w.Date >= DateTime.UtcNow).FirstOrDefault();
weekSeq = week.SEQ;
}
if (week != null)
{
PrepareLineMessage();
}
else
{
PrepareAllTaskMessage();
}
return true;
};
return false;
}
private void PrepareAllTaskMessage()
{
this.lineMessages = null;
StringBuilder messageContent = new StringBuilder();
messageContent.AppendLine("{ ");
messageContent.AppendLine(" \"altText\": \"幸福小組 8 週分工\", ");
messageContent.AppendLine(" \"type\": \"flex\", ");
messageContent.AppendLine(" \"contents\": { ");
messageContent.AppendLine(" \"type\": \"carousel\", ");
messageContent.AppendLine(" \"contents\": [ ");
foreach (var week in pastoralDomain.HappinessWeeks.OrderBy(w => w.SEQ))
{
messageContent.AppendLine("{ ");
messageContent.AppendLine(" \"type\": \"bubble\", ");
messageContent.AppendLine(" \"header\": { ");
messageContent.AppendLine(" \"type\": \"box\", ");
messageContent.AppendLine(" \"layout\": \"vertical\", ");
messageContent.AppendLine(" \"contents\": [ ");
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"text\", ");
messageContent.AppendLine($" \"text\": \"W{week.SEQ} {week.Topic} 分工表\", ");
messageContent.AppendLine(" \"flex\": 0, ");
messageContent.AppendLine(" \"size\": \"lg\", ");
messageContent.AppendLine(" \"weight\": \"bold\", ");
messageContent.AppendLine(" \"wrap\": false, ");
messageContent.AppendLine(" \"align\": \"center\" ");
messageContent.AppendLine(" } ");
messageContent.AppendLine(" ], ");
messageContent.AppendLine(" \"paddingAll\": \"sm\" ");
messageContent.AppendLine(" }, ");
messageContent.AppendLine(" \"hero\": { ");
messageContent.AppendLine(" \"type\": \"box\", ");
messageContent.AppendLine(" \"layout\": \"vertical\", ");
messageContent.AppendLine(" \"contents\": [ ");
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"image\", ");
messageContent.AppendLine($" \"url\": \"https://happiness.tours/assets/images/HappinessGroup/week0{week.SEQ}.jpg\", ");
messageContent.AppendLine(" \"size\": \"full\", ");
messageContent.AppendLine(" \"aspectRatio\": \"1.5:1\" ");
messageContent.AppendLine(" } ");
messageContent.AppendLine(" ] ");
messageContent.AppendLine(" }, ");
messageContent.AppendLine(" \"body\": { ");
messageContent.AppendLine(" \"type\": \"box\", ");
messageContent.AppendLine(" \"layout\": \"vertical\", ");
messageContent.AppendLine(" \"contents\": [ ");
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"text\", ");
messageContent.AppendLine(" \"text\": \"分工明細\", ");
messageContent.AppendLine(" \"flex\": 0, ");
messageContent.AppendLine(" \"size\": \"md\", ");
messageContent.AppendLine(" \"offsetBottom\": \"md\", ");
messageContent.AppendLine(" \"weight\": \"bold\", ");
messageContent.AppendLine(" \"wrap\": false ");
messageContent.AppendLine(" }, ");
foreach (var task in week.Tasks)
{
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"box\", ");
messageContent.AppendLine(" \"layout\": \"baseline\", ");
messageContent.AppendLine(" \"contents\": [ ");
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"text\", ");
messageContent.AppendLine($" \"text\": \"{task.Type.EnumToDescriptionString()}\", ");
messageContent.AppendLine(" \"flex\": 3, ");
messageContent.AppendLine(" \"size\": \"sm\", ");
messageContent.AppendLine(" \"weight\": \"regular\", ");
messageContent.AppendLine(" \"color\": \"#aaaaaa\", ");
messageContent.AppendLine(" \"wrap\": false ");
messageContent.AppendLine(" }, ");
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"text\", ");
messageContent.AppendLine($" \"text\": \"{task.Tasker} \", ");
messageContent.AppendLine(" \"flex\": 3, ");
messageContent.AppendLine(" \"size\": \"sm\", ");
messageContent.AppendLine(" \"weight\": \"regular\", ");
messageContent.AppendLine(" \"color\": \"#666666\", ");
messageContent.AppendLine(" \"wrap\": true ");
messageContent.AppendLine(" }, ");
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"text\", ");
messageContent.AppendLine($" \"text\": \"內容:{task.Content}\", ");
messageContent.AppendLine(" \"flex\": 7, ");
messageContent.AppendLine(" \"size\": \"sm\", ");
messageContent.AppendLine(" \"weight\": \"regular\", ");
messageContent.AppendLine(" \"color\": \"#666666\", ");
messageContent.AppendLine(" \"wrap\": true ");
messageContent.AppendLine(" } ");
messageContent.AppendLine(" ] ");
messageContent.AppendLine(" }, ");
}
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"separator\", ");
messageContent.AppendLine(" \"margin\": \"md\" ");
messageContent.AppendLine(" } ");
messageContent.AppendLine(" ], ");
messageContent.AppendLine(" \"paddingBottom\": \"none\" ");
messageContent.AppendLine(" }, ");
messageContent.AppendLine(" \"footer\": { ");
messageContent.AppendLine(" \"type\": \"box\", ");
messageContent.AppendLine(" \"layout\": \"vertical\", ");
messageContent.AppendLine(" \"contents\": [ ");
messageContent.AppendLine(" { ");
messageContent.AppendLine(" \"type\": \"button\", ");
messageContent.AppendLine(" \"action\": { ");
messageContent.AppendLine(" \"type\": \"uri\", ");
messageContent.AppendLine(" \"label\": \"管理分工\", ");
messageContent.AppendLine($" \"uri\": \"https://happiness.tours/myapp/happinessWeeks/395BBPTU4NG3F?openExternalBrowser={week.SEQ}\" ");
messageContent.AppendLine(" }, ");
messageContent.AppendLine(" \"style\": \"link\", ");
messageContent.AppendLine(" \"height\": \"md\" ");
messageContent.AppendLine(" } ");
messageContent.AppendLine(" ], ");
messageContent.AppendLine(" \"paddingAll\": \"none\" ");
messageContent.AppendLine(" } ");
if (week.SEQ < 8)
{
messageContent.AppendLine(" }, ");
}
else
{
messageContent.AppendLine(" } ");
}
}
messageContent.AppendLine(" ] ");
messageContent.AppendLine(" } ");
messageContent.AppendLine(" } ");
this.jsonMessage = messageContent.ToString();
}
private void PrepareLineMessage()
{
var random = new Random();
List<ILineMessage> list = new List<ILineMessage>();
@ -142,58 +332,22 @@ namespace WebAPI.Services.AutoReplyCommands
bodyContent.Add(new LineFlexSeparator());
#endregion
#region Footer
//flexMessage.Contents.InitFooter()
// .Add(
// new LineFlexButton()
// {
// Action = new UriAction()
// {
// Uri = "https://happiness.tours/CellGroup/dinner?openExternalBrowser=1",
// Label = "我的菜單"
// }
// }
// );
flexMessage.Contents.InitFooter()
.Add(
new LineFlexButton()
{
Action = new UriAction()
{
Uri = $"https://happiness.tours/myapp/happinessWeeks/{pastoralDomain.Id}",
Label = "管理分工"
}
}
);
#endregion
list.Insert(0, flexMessage);
return list;
}
}
public void Initialize(PastoralDomain pastoralDomain = null)
{
this.pastoralDomain = pastoralDomain;
}
private int weekSeq = 0;
private HappinessWeek week = null;
public bool Enabled(PastoralDomain pastoralDomain = null, string command = null)
{
if (pastoralDomain != null && COMMANDS.Any(c => c.IndexOf(command) == 0))
{
this.pastoralDomain = pastoralDomain;
command = command.Replace("分工", "");
if (command.Length > 0)
{
weekSeq = int.Parse(command);
}
logic.GetHappinessGroupInfo(pastoralDomain);
if (weekSeq > 0)
{
week = pastoralDomain.HappinessWeeks.Where(w => w.SEQ == weekSeq).FirstOrDefault();
}
else
{
week = pastoralDomain.HappinessWeeks.Where(w => w.Date >= DateTime.UtcNow).FirstOrDefault();
weekSeq = week.SEQ;
}
return true;
};
return false;
this.lineMessages = list;
}
}
}

View File

@ -13,6 +13,7 @@ namespace WebAPI.Services.Interfaces
string Description { get; }
IEnumerable<string> Commands { get; }
string ReplyTextMessage { get; }
string ReplyJsonMessage { get; }
IEnumerable<DomainType> SupportGroups { get; }
IEnumerable<ILineMessage> LineMessage { get; }
bool Enabled(PastoralDomain pastoralDomain = null, string command = null);

View File

@ -8,6 +8,7 @@ namespace WebAPI.Services.Interfaces
{
public interface IScheduledTask
{
static DateTime? NextRunningTime { get; set; }
string Description { get; }
bool CheckTime(DateTime time);
Task<bool> RunTask();

View File

@ -1,4 +1,5 @@
using Church.Net.Entity;
using Church.Net.DAL.EFCoreDBF;
using Church.Net.Entity;
using Church.Net.Entity.Messenger;
using Church.Net.Utility;
using LineMessaging;
@ -35,6 +36,7 @@ namespace WebAPI.Services
private readonly ILoggingService loggingService;
private readonly ICrudLogic<LineMessageClient> clientLogic;
private readonly LineMessagingAccountLogic lineMessagingAccountLogic;
private readonly ICrudDAL<LineMessagingAccount> lineAccountCrudDAL;
private string chatToken;
private PastoralDomain cellGroup;
@ -43,13 +45,15 @@ namespace WebAPI.Services
IEnumerable<IAutoReplyCommand> autoReplyCommands,
ILoggingService loggingService,
ICrudLogic<LineMessageClient> clientLogic,
LineMessagingAccountLogic lineMessagingAccountLogic
LineMessagingAccountLogic lineMessagingAccountLogic,
ICrudDAL<LineMessagingAccount> lineAccountCrudDAL
)
{
this.autoReplyCommands = autoReplyCommands;
this.loggingService = loggingService;
this.clientLogic = clientLogic;
this.lineMessagingAccountLogic = lineMessagingAccountLogic;
this.lineAccountCrudDAL = lineAccountCrudDAL;
}
public void SendTextMessage(string text, LineGroup target)
{
@ -96,6 +100,35 @@ namespace WebAPI.Services
return false;
}
}
public async Task<bool> ReplyJsonMessage(string lineId, string jsonMessage)
{
var test = new LineMessagingClient(this.chatToken);
//var replyMessage = new LineReplyMessage() { ReplyToken = replyToken };
//var messages = new List<ILineMessage>();
//foreach (var message in textMessages)
//{
// messages.Add(new LineTextMessage() { Text = message });
//}
//replyMessage.Messages = messages;
//test.ReplyMessage(replyMessage);
try
{
await test.PushJsonMessage(lineId, jsonMessage);
return true;
}
catch (Exception ex)
{
this.loggingService.Error(ex, "ReplyTextMessage:75", jsonMessage);
if (ex.Message == "You have reached your monthly limit.")
{
this.SendTextMessage("Line Bot Exist Monthly Limit!!!", LineGroup.Chris);
}
return false;
}
}
public async Task<bool> ReplyLineMessage(string lineId, IEnumerable<ILineMessage> lineMessages)
{
var test = new LineMessagingClient(this.chatToken);
@ -212,6 +245,10 @@ namespace WebAPI.Services
{
await ReplyLineMessage(target, autoReply.LineMessage);
}
else if (autoReply.ReplyJsonMessage != null)
{
await ReplyJsonMessage(target, autoReply.ReplyJsonMessage);
}
else
{
await ReplyTextMessage(replyToken, autoReply.ReplyTextMessage);
@ -260,7 +297,7 @@ namespace WebAPI.Services
{
try
{
cellGroup = group;
if (command.IndexOf("#") == 0)
{
command = command.ToLower().Substring(1);
@ -271,6 +308,9 @@ namespace WebAPI.Services
if (autoReply != null)
{
this.chatToken = this.lineAccountCrudDAL.First(x => x.Id == group.LineAccountId)?.ChatToken;
if (false == string.IsNullOrEmpty(this.chatToken))
{
if (autoReply.LineMessage != null)
{
await ReplyLineMessage(cellGroup.LineGroupId, autoReply.LineMessage);
@ -279,7 +319,7 @@ namespace WebAPI.Services
{
await ReplyTextMessage(cellGroup.LineGroupId, autoReply.ReplyTextMessage);
}
}
return true;
}
//else if (command == "help" || command == "?")

View File

@ -11,7 +11,8 @@ namespace WebAPI.Services.ScheduledTask
private readonly LineAutoBotService lineAutoBotService;
private readonly ILoggingService loggingService;
private readonly PastoralDomainLogic pastoralDomainLogic;
private DateTime? nextRunningTime = null;
public static DateTime? NextRunningTime = null;
public MorningPrayer(
LineAutoBotService lineAutoBotService,
ILoggingService loggingService,
@ -21,19 +22,19 @@ namespace WebAPI.Services.ScheduledTask
this.lineAutoBotService = lineAutoBotService;
this.loggingService = loggingService;
this.pastoralDomainLogic = pastoralDomainLogic;
this.SetNextRunningTime();
//this.SetNextRunningTime();
}
public string Description => "Sent out Ark Morning Prayer";
public bool CheckTime(DateTime time)
{
if(nextRunningTime == null)
if(NextRunningTime == null)
{
this.SetNextRunningTime();
return true;
return false;
}
return time >= nextRunningTime.Value;
return time >= NextRunningTime.Value;
}
public Task<bool> RunTask()
@ -53,8 +54,8 @@ namespace WebAPI.Services.ScheduledTask
}
private void SetNextRunningTime()
{
nextRunningTime = DateTimeHelper.Today().AddDays(1).AddHours(8);
loggingService.Log($"Scheduled Task {this.Description}", nextRunningTime.Value);
NextRunningTime = DateTimeHelper.Today().AddDays(1).AddHours(8);
loggingService.Log($"Scheduled Task {this.Description}", NextRunningTime.Value);
}
}
}

View File

@ -70,7 +70,8 @@ namespace WebAPI
services.AddDbContext<ChurchNetContext>(options =>
options.UseNpgsql(
//Configuration.GetConnectionString()
"Host=192.168.86.131;Port=49154;Database=ChurchSandbox;Username=chris;Password=1124"
//"Host=192.168.86.131;Port=49154;Database=ChurchSandbox;Username=chris;Password=1124"
"Host=192.168.86.131;Port=49154;Database=Church;Username=chris;Password=1124"
));
services.AddScoped<LineAutoBotService>();
@ -94,8 +95,7 @@ namespace WebAPI
services.AddScoped<LineMessagingAccountLogic>();
services.AddScoped<ILoggingService, DbLoggingService>();
services.AddScoped<IdentityService>();
services.AddScoped<ICrudLogic<FamilyMember>, MemberLogic>();
services.AddHostedService<WorkerService>();
//services.AddMvc(o=>o.Filters.Add(typeof(HandleExceptionFilter)));
//services.AddMvc(o => o.Filters.Add(new HandleExceptionFilter(services.BuildServiceProvider().GetService<ILoggingService>())));