whole project pushed
This commit is contained in:
@ -1,6 +1,10 @@
|
||||
using System;
|
||||
// Make sure these 'using' directives are at the top of your file
|
||||
using boilerplate.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity; // This is required for .ToListAsync()
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
@ -8,10 +12,24 @@ namespace boilerplate.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
// Add an instance of your database context
|
||||
private boilerplateEntities db = new boilerplateEntities();
|
||||
|
||||
// GET: Default
|
||||
public ActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// This action now fetches news from the database
|
||||
public async Task<ActionResult> AllNews()
|
||||
{
|
||||
// Fetch all news, order by the most recent ones
|
||||
var newsList = await db.News.OrderByDescending(n => n.News_Date).ToListAsync();
|
||||
return View(newsList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,17 @@
|
||||
using boilerplate.Models;
|
||||
using Microsoft.Ajax.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
|
||||
using System.Data.Entity.Infrastructure;
|
||||
using System.Data.Entity.SqlServer;
|
||||
using System.Globalization;
|
||||
using System.Data.Entity.Validation;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.UI.WebControls;
|
||||
using ClosedXML.Excel;
|
||||
|
||||
namespace boilerplate.Controllers
|
||||
{
|
||||
@ -28,236 +25,322 @@ namespace boilerplate.Controllers
|
||||
if (!HasSession()) { return RedirectToAction("Login"); }
|
||||
if (HasSession("ManageDashboard"))
|
||||
{
|
||||
var user = Session["User"] as User;
|
||||
|
||||
ViewBag.Title = "داشبورد";
|
||||
ViewBag.Counter1 = db.Users.Count();
|
||||
ViewBag.Counter2 = db.Users.Count();
|
||||
ViewBag.Counter3 = db.Users.Count();
|
||||
ViewBag.Counter4 = db.Users.Count();
|
||||
ViewBag.Counter5 = db.Users.Count();
|
||||
ViewBag.Counter6 = db.Users.Count();
|
||||
}
|
||||
return View();
|
||||
}
|
||||
|
||||
// --- User Management Actions ---
|
||||
public async Task<ActionResult> Users()
|
||||
{
|
||||
List<UserModel> models = new List<UserModel>();
|
||||
|
||||
if (!HasSession("ManageUser")) { return RedirectToAction("Index"); }
|
||||
models = db.Users.AsNoTracking().Select(x => new UserModel
|
||||
var models = await db.Users.AsNoTracking().Select(x => new UserModel
|
||||
{
|
||||
Id = x.User_Id,
|
||||
Name = x.User_Name,
|
||||
Family = x.User_Family,
|
||||
Phone = x.User_Phone,
|
||||
Code = x.User_Code,
|
||||
Status = x.User_Status,
|
||||
Role = x.User_Role,
|
||||
Status = x.User_Status,
|
||||
CreatedDate = x.User_CreatedDateFa
|
||||
}).ToList();
|
||||
|
||||
}).ToListAsync();
|
||||
return View(models);
|
||||
}
|
||||
|
||||
public new async Task<ActionResult> User(int Id = 0)
|
||||
{
|
||||
if (!HasSession("ManageUser")) { return new HttpStatusCodeResult(HttpStatusCode.Unauthorized); }
|
||||
var model = new User()
|
||||
{
|
||||
User_Id = Id,
|
||||
User_Status = 1,
|
||||
User_Image = "dUser.png"
|
||||
};
|
||||
if (Id != 0)
|
||||
{
|
||||
|
||||
|
||||
model = db.Users.AsNoTracking().Where(x => x.User_Id == Id).FirstOrDefault();
|
||||
User model;
|
||||
if (Id == 0)
|
||||
{
|
||||
model = new User() { User_Id = 0, User_Status = 1, User_Image = "dUser.png" };
|
||||
}
|
||||
else
|
||||
{
|
||||
model = await db.Users.AsNoTracking().FirstOrDefaultAsync(x => x.User_Id == Id);
|
||||
if (model == null) { return RedirectToAction("Users"); }
|
||||
|
||||
}
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[Route("~/panel/Setting")]
|
||||
public async Task<ActionResult> Setting()
|
||||
// --- News Management Actions (Reverted to simple version) ---
|
||||
public async Task<ActionResult> NewsList()
|
||||
{
|
||||
if (!HasSession("ManageNews")) { return RedirectToAction("Index"); }
|
||||
|
||||
var model = new Setting()
|
||||
var news = await db.News.OrderByDescending(n => n.News_Date).ToListAsync();
|
||||
return View(news);
|
||||
}
|
||||
|
||||
// --- News Management Actions ---
|
||||
// --- News Management Actions ---
|
||||
public class AddNewsViewModel
|
||||
{
|
||||
public News News { get; set; }
|
||||
public List<Item> AllCategories { get; set; }
|
||||
public List<Item> AllTags { get; set; }
|
||||
}
|
||||
|
||||
public async Task<ActionResult> AddNews(int id = 0)
|
||||
{
|
||||
if (!HasSession("ManageNews")) { return RedirectToAction("Index"); }
|
||||
|
||||
var allItems = await db.Items.ToListAsync();
|
||||
var categories = allItems.Where(i => i.Item_Type == "1").ToList();
|
||||
var tags = allItems.Where(i => i.Item_Type == "2").ToList();
|
||||
|
||||
var viewModel = new AddNewsViewModel
|
||||
{
|
||||
Setting_Id = 1,
|
||||
Setting_Social = "[]",
|
||||
Setting_Send = false,
|
||||
AllCategories = categories,
|
||||
AllTags = tags
|
||||
};
|
||||
if (!HasSession("ManageSetting")) { return RedirectToAction("Index"); }
|
||||
|
||||
model = db.Settings.AsNoTracking().FirstOrDefault();
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[Route("~/panel/SaveSettings")]
|
||||
[HttpPost]
|
||||
public async Task<JsonResult> SaveSettings()
|
||||
{
|
||||
StatusModel statusModel = new StatusModel() { Status = "Success" };
|
||||
|
||||
try
|
||||
if (id == 0)
|
||||
{
|
||||
if (HasSession())
|
||||
{
|
||||
var User = Session["User"] as User;
|
||||
if (HasSession("ManageSetting")
|
||||
)
|
||||
{
|
||||
SettingModel model = JsonConvert.DeserializeObject<SettingModel>(Request.Form["Model"]);
|
||||
var Settings = await db.Settings.FirstOrDefaultAsync();
|
||||
if (Settings != null)
|
||||
{
|
||||
Settings.Setting_Name = model.Name;
|
||||
Settings.Setting_Title = model.Title;
|
||||
Settings.Setting_Discount = model.Discount;
|
||||
Settings.Setting_Description = model.Description;
|
||||
Settings.Setting_Keywords = model.Keywords;
|
||||
Settings.Setting_Footer = model.Footer;
|
||||
Settings.Setting_Header = model.Header;
|
||||
Settings.Setting_Social = JsonConvert.SerializeObject(model.Socials);
|
||||
Settings.Setting_Username = model.SmsUsername;
|
||||
Settings.Setting_Password = model.SmsPassword;
|
||||
Settings.Setting_FromNumber = model.SmsFromNumber;
|
||||
Settings.Setting_PaternLogin = model.SmsPaternLogin;
|
||||
Settings.Setting_Address = model.address;
|
||||
Settings.Setting_PostCode = model.postcode;
|
||||
Settings.Setting_Phone = model.phone;
|
||||
Settings.Setting_Website = model.website;
|
||||
db.Entry(Settings).State = EntityState.Modified;
|
||||
for (int i = 0; i < Request.Files.Count; i++)
|
||||
{
|
||||
switch (Request.Files.AllKeys[i])
|
||||
{
|
||||
case "Logo":
|
||||
Request.Files[i].SaveAs(Server.MapPath($"~/Media/logo.png"));
|
||||
break;
|
||||
case "Icon":
|
||||
Request.Files[i].SaveAs(Server.MapPath($"~/Media/favicon.ico"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { statusModel.Status = "Auth"; }
|
||||
ViewBag.PageTitle = "افزودن خبر جدید";
|
||||
viewModel.News = new News { News_Date = DateTime.Now };
|
||||
}
|
||||
catch { statusModel.Status = "Error"; }
|
||||
return Json(statusModel);
|
||||
else
|
||||
{
|
||||
var news = await db.News.FindAsync(id);
|
||||
if (news == null) { return HttpNotFound(); }
|
||||
ViewBag.PageTitle = "ویرایش خبر";
|
||||
viewModel.News = news;
|
||||
}
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<JsonResult> Login(LoginModel model)
|
||||
[ValidateInput(false)]
|
||||
public async Task<ActionResult> AddNews(AddNewsViewModel viewModel, HttpPostedFileBase imageFile, string[] selectedCategories, string[] selectedTags)
|
||||
{
|
||||
StatusModel statusModel = new StatusModel() { Status = "Success" };
|
||||
if (!HasSession("ManageNews")) { return RedirectToAction("Index"); }
|
||||
|
||||
// Join multiple selections into comma-separated strings
|
||||
viewModel.News.News_Category = selectedCategories != null ? string.Join(",", selectedCategories) : "";
|
||||
viewModel.News.News_Tag = selectedTags != null ? string.Join(",", selectedTags) : "";
|
||||
|
||||
// *** ADDED: Server-side validation for required fields ***
|
||||
if (viewModel.News.News_ID == 0 && (imageFile == null || imageFile.ContentLength == 0))
|
||||
{
|
||||
ModelState.AddModelError("imageFile", "لطفاً یک تصویر برای خبر انتخاب کنید.");
|
||||
}
|
||||
if (selectedCategories == null || !selectedCategories.Any())
|
||||
{
|
||||
ModelState.AddModelError("selectedCategories", "انتخاب حداقل یک دستهبندی الزامی است.");
|
||||
}
|
||||
if (selectedTags == null || !selectedTags.Any())
|
||||
{
|
||||
ModelState.AddModelError("selectedTags", "انتخاب حداقل یک تگ الزامی است.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(model.Username) && !string.IsNullOrEmpty(model.Password))
|
||||
var model = viewModel.News;
|
||||
if (imageFile != null && imageFile.ContentLength > 0)
|
||||
{
|
||||
var User = await db.Users.Where(x => x.User_Phone == model.Username && x.User_Role == "Admin").FirstOrDefaultAsync();
|
||||
if (User != null)
|
||||
var uploadDir = "~/Media/News";
|
||||
if (!Directory.Exists(Server.MapPath(uploadDir)))
|
||||
{
|
||||
if (User.User_Status == 1)
|
||||
{
|
||||
if (User.User_Password == functions.HashPassword(model.Password + User.User_CreatedDate))
|
||||
{
|
||||
DateTime Now = DateTime.Now;
|
||||
string Token = functions.GenerateToken();
|
||||
User.User_LoginDate = Now;
|
||||
User.User_LoginDateFa = functions.ConvertToPersianDate(Now);
|
||||
User.User_Token = Token;
|
||||
await db.SaveChangesAsync();
|
||||
Session["User"] = User;
|
||||
SetCookie("UserId", $"{User.User_Id}");
|
||||
SetCookie("Token", Token);
|
||||
|
||||
|
||||
}
|
||||
else { statusModel.Status = "Wrong"; }
|
||||
}
|
||||
else { statusModel.Status = "Block"; }
|
||||
Directory.CreateDirectory(Server.MapPath(uploadDir));
|
||||
}
|
||||
else { statusModel.Status = "NoExist"; }
|
||||
var fileName = Guid.NewGuid().ToString() + Path.GetExtension(imageFile.FileName);
|
||||
var path = Path.Combine(Server.MapPath(uploadDir), fileName);
|
||||
imageFile.SaveAs(path);
|
||||
model.News_IMG = fileName;
|
||||
}
|
||||
else { statusModel.Status = "Empty"; }
|
||||
|
||||
if (model.News_ID == 0)
|
||||
{
|
||||
model.News_CreateDate = DateTime.Now;
|
||||
model.News_Date = DateTime.Now;
|
||||
db.News.Add(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
model.News_EditDate = DateTime.Now;
|
||||
db.Entry(model).State = EntityState.Modified;
|
||||
if (imageFile == null)
|
||||
{
|
||||
db.Entry(model).Property(x => x.News_IMG).IsModified = false;
|
||||
}
|
||||
}
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
return RedirectToAction("NewsList");
|
||||
}
|
||||
else { statusModel.Status = "NotValid"; }
|
||||
}
|
||||
catch { statusModel.Status = "Error"; }
|
||||
return Json(statusModel);
|
||||
catch (Exception ex)
|
||||
{
|
||||
ModelState.AddModelError("", "یک خطای پیشبینی نشده رخ داد: " + ex.Message);
|
||||
}
|
||||
|
||||
// If we get here, something failed. Repopulate the dropdowns.
|
||||
var allItems = await db.Items.ToListAsync();
|
||||
viewModel.AllCategories = allItems.Where(i => i.Item_Type == "1").ToList();
|
||||
viewModel.AllTags = allItems.Where(i => i.Item_Type == "2").ToList();
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[Route("~/Panel/Logout")]
|
||||
public async Task Logout()
|
||||
|
||||
[HttpPost]
|
||||
public async Task<JsonResult> DeleteNews(int id)
|
||||
{
|
||||
if (Session["User"] != null)
|
||||
if (!HasSession("ManageNews")) { return Json(new { success = false }); }
|
||||
|
||||
var news = await db.News.FindAsync(id);
|
||||
if (news != null)
|
||||
{
|
||||
var UserModel = Session["User"] as User;
|
||||
var Single = await db.Users.FindAsync(UserModel.User_Id);
|
||||
if (Single != null)
|
||||
var imagePath = Server.MapPath("~/Media/News/" + news.News_IMG);
|
||||
if (System.IO.File.Exists(imagePath))
|
||||
{
|
||||
Single.User_Token = null;
|
||||
System.IO.File.Delete(imagePath);
|
||||
}
|
||||
|
||||
db.News.Remove(news);
|
||||
await db.SaveChangesAsync();
|
||||
return Json(new { success = true });
|
||||
}
|
||||
return Json(new { success = false });
|
||||
}
|
||||
|
||||
// --- Item (Category/Tag) Management Actions ---
|
||||
public async Task<ActionResult> Items(int id)
|
||||
{
|
||||
if (!HasSession("ManageItems")) { return RedirectToAction("Index"); }
|
||||
|
||||
string itemTypeString = id.ToString();
|
||||
ViewBag.ItemType = id;
|
||||
ViewBag.PageTitle = (id == 1) ? "مدیریت دستهبندیها" : "مدیریت تگها";
|
||||
ViewBag.NewItemLabel = (id == 1) ? "نام دستهبندی جدید" : "نام تگ جدید";
|
||||
|
||||
var items = await db.Items.Where(i => i.Item_Type == itemTypeString).ToListAsync();
|
||||
return View(items);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<ActionResult> AddItem(Item model)
|
||||
{
|
||||
if (!HasSession("ManageItems")) { return RedirectToAction("Index"); }
|
||||
|
||||
if (ModelState.IsValid && !string.IsNullOrWhiteSpace(model.Item_Title))
|
||||
{
|
||||
bool exists = await db.Items.AnyAsync(i => i.Item_Title == model.Item_Title && i.Item_Type == model.Item_Type);
|
||||
if (!exists)
|
||||
{
|
||||
db.Items.Add(model);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
Session.Clear();
|
||||
Session.Abandon();
|
||||
SetCookie("UserId", "", -1);
|
||||
SetCookie("UserToken", "", -1);
|
||||
Response.Redirect("~/Panel/Login");
|
||||
return RedirectToAction("Items", new { id = Convert.ToInt32(model.Item_Type) });
|
||||
}
|
||||
[Route("~/Login")]
|
||||
[Route("Login")]
|
||||
public async Task<ActionResult> Login(string Return = "")
|
||||
|
||||
[HttpPost]
|
||||
public async Task<JsonResult> DeleteItem(int id)
|
||||
{
|
||||
ViewBag.Return = Return;
|
||||
if (Session["User"] != null)
|
||||
if (!HasSession("ManageItems")) { return Json(new { success = false }); }
|
||||
|
||||
var item = await db.Items.FindAsync(id);
|
||||
if (item != null)
|
||||
{
|
||||
Response.Redirect("~/panel/index");
|
||||
db.Items.Remove(item);
|
||||
await db.SaveChangesAsync();
|
||||
return Json(new { success = true });
|
||||
}
|
||||
else if (UserSessionExists()) { Response.Redirect("~/panel/Index"); }
|
||||
return View();
|
||||
return Json(new { success = false });
|
||||
}
|
||||
|
||||
// --- Settings Action ---
|
||||
[Route("~/panel/Setting")]
|
||||
public async Task<ActionResult> Setting()
|
||||
{
|
||||
if (!HasSession("ManageSetting")) { return RedirectToAction("Index"); }
|
||||
|
||||
var model = await db.Settings.AsNoTracking().FirstOrDefaultAsync();
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
model = new Setting();
|
||||
}
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
// --- Authentication and Session Management ---
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<JsonResult> Login(LoginModel model)
|
||||
{
|
||||
StatusModel statusModel = new StatusModel() { Status = "Success", RedirectUrl = "" };
|
||||
try
|
||||
{
|
||||
if (ModelState.IsValid && !string.IsNullOrEmpty(model.Username) && !string.IsNullOrEmpty(model.Password))
|
||||
{
|
||||
var user = await db.Users.FirstOrDefaultAsync(x => x.User_Phone == model.Username);
|
||||
|
||||
if (user != null && user.User_Status == 1)
|
||||
{
|
||||
if (string.Equals(user.User_Role, "Admin", StringComparison.OrdinalIgnoreCase) &&
|
||||
user.User_Password == functions.HashPassword(model.Password + user.User_CreatedDate))
|
||||
{
|
||||
Session["User"] = user;
|
||||
SetCookie("UserId", $"{user.User_Id}");
|
||||
SetCookie("Token", functions.GenerateToken());
|
||||
statusModel.RedirectUrl = "/Panel/Index";
|
||||
}
|
||||
else { statusModel.Status = "Wrong"; }
|
||||
}
|
||||
else if (user != null) { statusModel.Status = "Block"; }
|
||||
else { statusModel.Status = "NoExist"; }
|
||||
}
|
||||
else { statusModel.Status = "Empty"; }
|
||||
}
|
||||
catch { statusModel.Status = "Error"; }
|
||||
|
||||
return Json(statusModel);
|
||||
}
|
||||
|
||||
bool UserSessionExists()
|
||||
{
|
||||
try
|
||||
{
|
||||
string Token = GetCookie("Token");
|
||||
decimal.TryParse(GetCookie("UserId"), out decimal UserId);
|
||||
if (!string.IsNullOrEmpty(Token) && UserId != 0)
|
||||
string tokenFromCookie = GetCookie("Token");
|
||||
string userIdFromCookie = GetCookie("UserId");
|
||||
|
||||
if (string.IsNullOrEmpty(tokenFromCookie) || string.IsNullOrEmpty(userIdFromCookie))
|
||||
{
|
||||
var Single = db.Users.Where(x => x.User_Id == UserId && x.User_Token == Token && x.User_Status == 1 && x.User_Role == "Admin").FirstOrDefault();
|
||||
if (Single != null)
|
||||
{
|
||||
Session["User"] = Single;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCookie("Token", "", -1);
|
||||
SetCookie("UserId", "", -1);
|
||||
}
|
||||
if (Session["User"] != null) { return true; }
|
||||
return false;
|
||||
}
|
||||
SetCookie("Token", "", -1);
|
||||
SetCookie("UserId", "", -1);
|
||||
|
||||
if (!int.TryParse(userIdFromCookie, out int userId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var user = db.Users.FirstOrDefault(x => x.User_Id == userId && x.User_Token == tokenFromCookie && x.User_Status == 1);
|
||||
|
||||
if (user != null && user.User_Role != null && string.Equals(user.User_Role.Trim(), "Admin", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Session["User"] = user;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCookie("Token", "", -1);
|
||||
SetCookie("UserId", "", -1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
bool HasSession(string Access = "")
|
||||
@ -266,107 +349,92 @@ namespace boilerplate.Controllers
|
||||
return string.IsNullOrEmpty(Access) || functions.HasAccess((Session["User"] as User).User_Access, Access);
|
||||
}
|
||||
|
||||
[Route("~/Verify")]
|
||||
[Route("Verify")]
|
||||
public ActionResult Verify(string Phone = "", string Return = "")
|
||||
[Route("~/Panel/Logout")]
|
||||
public async Task Logout()
|
||||
{
|
||||
Session.Clear();
|
||||
Session.Abandon();
|
||||
SetCookie("UserId", "", -1);
|
||||
SetCookie("Token", "", -1);
|
||||
Response.Redirect("~/Panel/Login");
|
||||
}
|
||||
|
||||
[Route("~/Login")]
|
||||
[Route("Login")]
|
||||
public ActionResult Login(string Return = "")
|
||||
{
|
||||
ViewBag.Return = Return;
|
||||
if (Session["User"] != null)
|
||||
{
|
||||
Response.Redirect("~/Index");
|
||||
}
|
||||
if (Phone == "")
|
||||
{
|
||||
Response.Redirect("~/Login");
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewBag.Phone = Phone;
|
||||
}
|
||||
if (UserSessionExists()) { Response.Redirect("~/panel/Index"); }
|
||||
return View();
|
||||
}
|
||||
//set session and cookies afte login
|
||||
|
||||
[HttpGet]
|
||||
[Route("Complete")]
|
||||
[Route("~/Complete")]
|
||||
public ActionResult Complete()
|
||||
public ActionResult Complete(int User, string Token)
|
||||
{
|
||||
try
|
||||
var user = db.Users.FirstOrDefault(u => u.User_Id == User && u.User_Token == Token);
|
||||
if (user != null)
|
||||
{
|
||||
// Log query parameters
|
||||
var user = Request.QueryString["User"];
|
||||
var token = Request.QueryString["Token"];
|
||||
|
||||
if (string.IsNullOrEmpty(user) || string.IsNullOrEmpty(token))
|
||||
{
|
||||
Console.WriteLine("User or Token is missing in the query string.");
|
||||
return new HttpStatusCodeResult(400, "Bad Request: User or Token missing.");
|
||||
}
|
||||
|
||||
// Log the query parameters
|
||||
Console.WriteLine($"User: {user}, Token: {token}");
|
||||
|
||||
var currentuser = db.Users
|
||||
.Where(x => x.User_Id.ToString() == user && x.User_Token.ToString() == token)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (currentuser != null)
|
||||
{
|
||||
// Perform necessary actions, like setting session and cookies
|
||||
Session["User"] = currentuser;
|
||||
SetCookie("UserId", $"{currentuser.User_Id}");
|
||||
SetCookie("Token", currentuser.User_Token);
|
||||
|
||||
// Log success
|
||||
Console.WriteLine("User authenticated and session updated.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log if user is not found
|
||||
Console.WriteLine("User not found.");
|
||||
return new HttpStatusCodeResult(404, "User not found.");
|
||||
}
|
||||
Session["User"] = user;
|
||||
SetCookie("UserId", user.User_Id.ToString());
|
||||
SetCookie("Token", user.User_Token);
|
||||
return new HttpStatusCodeResult(HttpStatusCode.OK);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log error details
|
||||
Console.WriteLine($"Error in Complete: {ex.Message}");
|
||||
return new HttpStatusCodeResult(500, "Internal Server Error: " + ex.Message);
|
||||
}
|
||||
|
||||
// Return a success response or redirect
|
||||
return new HttpStatusCodeResult(200, "Request completed successfully.");
|
||||
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
string SetCookie(string Key, string Value, int ExpireDay = 365)
|
||||
{
|
||||
try
|
||||
var cookie = new HttpCookie(Key, Value)
|
||||
{
|
||||
Response.Cookies.Add(new HttpCookie(Key, Value) { Expires = DateTime.Now.AddDays(ExpireDay) });
|
||||
}
|
||||
catch { }
|
||||
Expires = DateTime.Now.AddDays(ExpireDay),
|
||||
Path = "/",
|
||||
SameSite = SameSiteMode.Lax
|
||||
};
|
||||
Response.Cookies.Add(cookie);
|
||||
return Value;
|
||||
}
|
||||
|
||||
string GetCookie(string Key)
|
||||
{
|
||||
string value = string.Empty;
|
||||
try
|
||||
var cookie = Request.Cookies[Key];
|
||||
return cookie?.Value ?? string.Empty;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<JsonResult> UpdateItem(int id, string newTitle)
|
||||
{
|
||||
if (!HasSession("ManageItems")) { return Json(new { success = false, message = "Unauthorized" }); }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(newTitle))
|
||||
{
|
||||
var cookie = Request.Cookies[Key];
|
||||
if (cookie != null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(cookie.Value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
value = cookie.Value;
|
||||
}
|
||||
return Json(new { success = false, message = "نام آیتم نمیتواند خالی باشد." });
|
||||
}
|
||||
catch { }
|
||||
return value;
|
||||
|
||||
var item = await db.Items.FindAsync(id);
|
||||
if (item != null)
|
||||
{
|
||||
// بررسی برای جلوگیری از ثبت نام تکراری
|
||||
bool exists = await db.Items.AnyAsync(i => i.Item_Title == newTitle && i.Item_Type == item.Item_Type && i.Item_Id != id);
|
||||
if (exists)
|
||||
{
|
||||
return Json(new { success = false, message = "این نام قبلاً ثبت شده است." });
|
||||
}
|
||||
|
||||
item.Item_Title = newTitle;
|
||||
await db.SaveChangesAsync();
|
||||
return Json(new { success = true });
|
||||
}
|
||||
return Json(new { success = false, message = "آیتم یافت نشد." });
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<ActionResult> ClientManagement()
|
||||
{
|
||||
if (!HasSession("ManageClients")) { return RedirectToAction("Index"); }
|
||||
var clients = await db.Clients.ToListAsync();
|
||||
return View(clients);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using boilerplate.Models;
|
||||
using ClosedXML.Excel;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -9,11 +10,13 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Http;
|
||||
|
||||
|
||||
namespace boilerplate.Controllers
|
||||
{
|
||||
public class UserController : ApiController
|
||||
@ -212,7 +215,7 @@ namespace boilerplate.Controllers
|
||||
user.User_Token = token;
|
||||
user.User_LoginDate = nowTime;
|
||||
user.User_LoginDateFa = functions.ConvertToPersianDate(nowTime);
|
||||
|
||||
|
||||
|
||||
db.SaveChanges();
|
||||
|
||||
@ -275,6 +278,7 @@ namespace boilerplate.Controllers
|
||||
Token = Token,
|
||||
Id = user.User_Id,
|
||||
Phone = user.User_Phone,
|
||||
role = user.User_Role,
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -319,5 +323,237 @@ namespace boilerplate.Controllers
|
||||
}
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
|
||||
[Route("api/Client/Import")]
|
||||
[HttpPost]
|
||||
public async Task<StatusModel> ImportClients()
|
||||
{
|
||||
var statusModel = new StatusModel { Status = "Success" };
|
||||
try
|
||||
{
|
||||
if (!Request.Content.IsMimeMultipartContent())
|
||||
{
|
||||
statusModel.Status = "InvalidRequest";
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
var provider = await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider());
|
||||
var formData = provider.FormData;
|
||||
|
||||
// ۱. احراز هویت و بررسی دسترسی
|
||||
var authModel = JsonConvert.DeserializeObject<AuthModel>(formData.Get("Auth"));
|
||||
var userAccessModel = functions.CheckUserAccess(authModel, new string[] { "Admin" }, new string[] { "All", "ManageClients" });
|
||||
|
||||
if (userAccessModel.Id == 0)
|
||||
{
|
||||
statusModel.Status = "Auth";
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
// ۲. دریافت فایل اکسل
|
||||
if (provider.Files.Count == 0)
|
||||
{
|
||||
statusModel.Status = "NoFile";
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
HttpContent excelFile = provider.Files[0];
|
||||
Stream excelStream = await excelFile.ReadAsStreamAsync();
|
||||
|
||||
// ۳. پردازش فایل اکسل با ClosedXML
|
||||
using (var workbook = new XLWorkbook(excelStream))
|
||||
{
|
||||
var worksheet = workbook.Worksheet(1);
|
||||
var rows = worksheet.RowsUsed().Skip(1); // نادیده گرفتن هدر
|
||||
|
||||
var clientsToAdd = new List<Client>();
|
||||
foreach (var row in rows)
|
||||
{
|
||||
if (row.Cell(1).IsEmpty()) continue;
|
||||
clientsToAdd.Add(new Client
|
||||
{
|
||||
Client_Name = row.Cell(1).GetValue<string>(),
|
||||
Client_LastName = row.Cell(2).GetValue<string>(),
|
||||
Client_PhoneNumber = row.Cell(3).GetValue<string>(),
|
||||
Client_UserName = row.Cell(4).GetValue<string>(),
|
||||
Client_Email = row.Cell(5).GetValue<string>()
|
||||
});
|
||||
}
|
||||
|
||||
// ۴. ذخیره در دیتابیس
|
||||
if (clientsToAdd.Any())
|
||||
{
|
||||
db.Clients.AddRange(clientsToAdd);
|
||||
await db.SaveChangesAsync();
|
||||
statusModel.Message = $"تعداد {clientsToAdd.Count} مشتری جدید با موفقیت اضافه شد.";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusModel.Status = "EmptyFile";
|
||||
statusModel.Message = "فایل اکسل خالی است یا ردیف معتبری ندارد.";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
statusModel.Status = "Error";
|
||||
statusModel.Message = ex.ToString(); // برگرداندن خطای کامل برای دیباگ
|
||||
}
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
[Route("api/Client/Export")]
|
||||
[HttpPost]
|
||||
public async Task<HttpResponseMessage> ExportClients([FromBody] AuthModel authModel)
|
||||
{
|
||||
// ۱. احراز هویت و بررسی دسترسی
|
||||
var userAccessModel = functions.CheckUserAccess(authModel, new string[] { "Admin" }, new string[] { "All", "ManageClients" });
|
||||
if (userAccessModel.Id == 0)
|
||||
{
|
||||
return Request.CreateResponse(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
// ۲. دریافت لیست مشتریان
|
||||
var clients = await db.Clients.ToListAsync();
|
||||
|
||||
// ۳. ساخت فایل اکسل در حافظه
|
||||
using (var workbook = new XLWorkbook())
|
||||
{
|
||||
var worksheet = workbook.Worksheets.Add("Clients");
|
||||
worksheet.Cell(1, 1).Value = "نام";
|
||||
worksheet.Cell(1, 2).Value = "نام خانوادگی";
|
||||
worksheet.Cell(1, 3).Value = "شماره تلفن";
|
||||
worksheet.Cell(1, 4).Value = "نام کاربری";
|
||||
worksheet.Cell(1, 5).Value = "ایمیل";
|
||||
worksheet.Row(1).Style.Font.Bold = true;
|
||||
|
||||
worksheet.Cell(2, 1).InsertData(clients);
|
||||
|
||||
// ۴. آمادهسازی پاسخ برای دانلود
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
workbook.SaveAs(stream);
|
||||
var content = stream.ToArray();
|
||||
|
||||
var result = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new ByteArrayContent(content)
|
||||
};
|
||||
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
||||
{
|
||||
FileName = $"Clients_{DateTime.Now:yyyyMMddHHmmss}.xlsx"
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Route("api/Client/Delete")]
|
||||
[HttpPost]
|
||||
public async Task<StatusModel> DeleteClient(AuthModel model)
|
||||
{
|
||||
StatusModel statusModel = new StatusModel() { Status = "Success" };
|
||||
try
|
||||
{
|
||||
// Check for admin privileges
|
||||
var userAccessModel = functions.CheckUserAccess(model, new string[] { "Admin" }, new string[] { "All", "ManageClients" });
|
||||
if (userAccessModel.Id == 0)
|
||||
{
|
||||
statusModel.Status = "Auth";
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
// Find and delete the client
|
||||
var clientToDelete = await db.Clients.FindAsync(model.Id);
|
||||
if (clientToDelete != null)
|
||||
{
|
||||
db.Clients.Remove(clientToDelete);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
statusModel.Status = "NotFound";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
statusModel.Status = "Error";
|
||||
statusModel.Message = ex.Message;
|
||||
}
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
|
||||
// --- این کلاس مدل را به فایل Models/UserModel.cs یا یک فایل جدید اضافه کنید ---
|
||||
public class ClientUpdateModel
|
||||
{
|
||||
public AuthModel Auth { get; set; }
|
||||
public Client Client { get; set; }
|
||||
}
|
||||
|
||||
// --- این متدها را به UserController.cs اضافه کنید ---
|
||||
|
||||
// API برای دریافت اطلاعات یک مشتری خاص (برای نمایش در فرم ویرایش)
|
||||
[Route("api/Client/Get/{id}")]
|
||||
[HttpPost]
|
||||
public async Task<HttpResponseMessage> GetClient(int id, [FromBody] AuthModel authModel)
|
||||
{
|
||||
var userAccessModel = functions.CheckUserAccess(authModel, new string[] { "Admin" }, new string[] { "All", "ManageClients" });
|
||||
if (userAccessModel.Id == 0)
|
||||
{
|
||||
return Request.CreateResponse(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
var client = await db.Clients.FindAsync(id);
|
||||
if (client == null)
|
||||
{
|
||||
return Request.CreateResponse(HttpStatusCode.NotFound);
|
||||
}
|
||||
return Request.CreateResponse(HttpStatusCode.OK, client);
|
||||
}
|
||||
|
||||
// API برای آپدیت اطلاعات یک مشتری
|
||||
[Route("api/Client/Update")]
|
||||
[HttpPost]
|
||||
public async Task<StatusModel> UpdateClient([FromBody] ClientUpdateModel model)
|
||||
{
|
||||
var statusModel = new StatusModel { Status = "Success" };
|
||||
try
|
||||
{
|
||||
var userAccessModel = functions.CheckUserAccess(model.Auth, new string[] { "Admin" }, new string[] { "All", "ManageClients" });
|
||||
if (userAccessModel.Id == 0)
|
||||
{
|
||||
statusModel.Status = "Auth";
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
var clientToUpdate = await db.Clients.FindAsync(model.Client.Client_Id);
|
||||
if (clientToUpdate != null)
|
||||
{
|
||||
// آپدیت کردن فیلدها
|
||||
clientToUpdate.Client_Name = model.Client.Client_Name;
|
||||
clientToUpdate.Client_LastName = model.Client.Client_LastName;
|
||||
clientToUpdate.Client_PhoneNumber = model.Client.Client_PhoneNumber;
|
||||
clientToUpdate.Client_UserName = model.Client.Client_UserName;
|
||||
clientToUpdate.Client_Email = model.Client.Client_Email;
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
statusModel.Status = "NotFound";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
statusModel.Status = "Error";
|
||||
statusModel.Message = ex.Message;
|
||||
}
|
||||
return statusModel;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user