whole project pushed
@ -59,5 +59,16 @@ namespace boilerplate.Areas.HelpPage.Controllers
|
|||||||
|
|
||||||
return View(ErrorViewName);
|
return View(ErrorViewName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UserController : Controller
|
||||||
|
{
|
||||||
|
// ???? ?????? ??? ?? ??? ?????? ...
|
||||||
|
|
||||||
|
// ??? ??? ?? ????? ????
|
||||||
|
public ActionResult AllNews()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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.Collections.Generic;
|
||||||
|
using System.Data.Entity; // This is required for .ToListAsync()
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
|
||||||
@ -8,10 +12,24 @@ namespace boilerplate.Controllers
|
|||||||
{
|
{
|
||||||
public class HomeController : Controller
|
public class HomeController : Controller
|
||||||
{
|
{
|
||||||
|
// Add an instance of your database context
|
||||||
|
private boilerplateEntities db = new boilerplateEntities();
|
||||||
|
|
||||||
// GET: Default
|
// GET: Default
|
||||||
public ActionResult Index()
|
public ActionResult Index()
|
||||||
{
|
{
|
||||||
return View();
|
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 boilerplate.Models;
|
||||||
using Microsoft.Ajax.Utilities;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
|
using System.Data.Entity.Validation;
|
||||||
using System.Data.Entity.Infrastructure;
|
using System.IO;
|
||||||
using System.Data.Entity.SqlServer;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.UI.WebControls;
|
using ClosedXML.Excel;
|
||||||
|
|
||||||
namespace boilerplate.Controllers
|
namespace boilerplate.Controllers
|
||||||
{
|
{
|
||||||
@ -28,236 +25,322 @@ namespace boilerplate.Controllers
|
|||||||
if (!HasSession()) { return RedirectToAction("Login"); }
|
if (!HasSession()) { return RedirectToAction("Login"); }
|
||||||
if (HasSession("ManageDashboard"))
|
if (HasSession("ManageDashboard"))
|
||||||
{
|
{
|
||||||
var user = Session["User"] as User;
|
|
||||||
|
|
||||||
ViewBag.Title = "داشبورد";
|
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();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- User Management Actions ---
|
||||||
public async Task<ActionResult> Users()
|
public async Task<ActionResult> Users()
|
||||||
{
|
{
|
||||||
List<UserModel> models = new List<UserModel>();
|
|
||||||
|
|
||||||
if (!HasSession("ManageUser")) { return RedirectToAction("Index"); }
|
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,
|
Id = x.User_Id,
|
||||||
Name = x.User_Name,
|
Name = x.User_Name,
|
||||||
Family = x.User_Family,
|
Family = x.User_Family,
|
||||||
Phone = x.User_Phone,
|
Phone = x.User_Phone,
|
||||||
Code = x.User_Code,
|
|
||||||
Status = x.User_Status,
|
|
||||||
Role = x.User_Role,
|
Role = x.User_Role,
|
||||||
|
Status = x.User_Status,
|
||||||
CreatedDate = x.User_CreatedDateFa
|
CreatedDate = x.User_CreatedDateFa
|
||||||
}).ToList();
|
}).ToListAsync();
|
||||||
|
|
||||||
return View(models);
|
return View(models);
|
||||||
}
|
}
|
||||||
|
|
||||||
public new async Task<ActionResult> User(int Id = 0)
|
public new async Task<ActionResult> User(int Id = 0)
|
||||||
{
|
{
|
||||||
if (!HasSession("ManageUser")) { return new HttpStatusCodeResult(HttpStatusCode.Unauthorized); }
|
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)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
User model;
|
||||||
model = db.Users.AsNoTracking().Where(x => x.User_Id == Id).FirstOrDefault();
|
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"); }
|
if (model == null) { return RedirectToAction("Users"); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("~/panel/Setting")]
|
// --- News Management Actions (Reverted to simple version) ---
|
||||||
public async Task<ActionResult> Setting()
|
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
|
||||||
{
|
{
|
||||||
Setting_Id = 1,
|
public News News { get; set; }
|
||||||
Setting_Social = "[]",
|
public List<Item> AllCategories { get; set; }
|
||||||
Setting_Send = false,
|
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
|
||||||
|
{
|
||||||
|
AllCategories = categories,
|
||||||
|
AllTags = tags
|
||||||
};
|
};
|
||||||
if (!HasSession("ManageSetting")) { return RedirectToAction("Index"); }
|
|
||||||
|
|
||||||
model = db.Settings.AsNoTracking().FirstOrDefault();
|
if (id == 0)
|
||||||
|
{
|
||||||
return View(model);
|
ViewBag.PageTitle = "افزودن خبر جدید";
|
||||||
|
viewModel.News = new News { News_Date = DateTime.Now };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var news = await db.News.FindAsync(id);
|
||||||
|
if (news == null) { return HttpNotFound(); }
|
||||||
|
ViewBag.PageTitle = "ویرایش خبر";
|
||||||
|
viewModel.News = news;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("~/panel/SaveSettings")]
|
return View(viewModel);
|
||||||
[HttpPost]
|
|
||||||
public async Task<JsonResult> SaveSettings()
|
|
||||||
{
|
|
||||||
StatusModel statusModel = new StatusModel() { Status = "Success" };
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
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"; }
|
|
||||||
}
|
|
||||||
catch { statusModel.Status = "Error"; }
|
|
||||||
return Json(statusModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ValidateAntiForgeryToken]
|
[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
|
try
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
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();
|
var uploadDir = "~/Media/News";
|
||||||
if (User != null)
|
if (!Directory.Exists(Server.MapPath(uploadDir)))
|
||||||
{
|
{
|
||||||
if (User.User_Status == 1)
|
Directory.CreateDirectory(Server.MapPath(uploadDir));
|
||||||
|
}
|
||||||
|
var fileName = Guid.NewGuid().ToString() + Path.GetExtension(imageFile.FileName);
|
||||||
|
var path = Path.Combine(Server.MapPath(uploadDir), fileName);
|
||||||
|
imageFile.SaveAs(path);
|
||||||
|
model.News_IMG = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.News_ID == 0)
|
||||||
{
|
{
|
||||||
if (User.User_Password == functions.HashPassword(model.Password + User.User_CreatedDate))
|
model.News_CreateDate = DateTime.Now;
|
||||||
|
model.News_Date = DateTime.Now;
|
||||||
|
db.News.Add(model);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
DateTime Now = DateTime.Now;
|
model.News_EditDate = DateTime.Now;
|
||||||
string Token = functions.GenerateToken();
|
db.Entry(model).State = EntityState.Modified;
|
||||||
User.User_LoginDate = Now;
|
if (imageFile == null)
|
||||||
User.User_LoginDateFa = functions.ConvertToPersianDate(Now);
|
{
|
||||||
User.User_Token = Token;
|
db.Entry(model).Property(x => x.News_IMG).IsModified = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
Session["User"] = User;
|
return RedirectToAction("NewsList");
|
||||||
SetCookie("UserId", $"{User.User_Id}");
|
}
|
||||||
SetCookie("Token", Token);
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<JsonResult> DeleteNews(int id)
|
||||||
|
{
|
||||||
|
if (!HasSession("ManageNews")) { return Json(new { success = false }); }
|
||||||
|
|
||||||
|
var news = await db.News.FindAsync(id);
|
||||||
|
if (news != null)
|
||||||
|
{
|
||||||
|
var imagePath = Server.MapPath("~/Media/News/" + news.News_IMG);
|
||||||
|
if (System.IO.File.Exists(imagePath))
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RedirectToAction("Items", new { id = Convert.ToInt32(model.Item_Type) });
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<JsonResult> DeleteItem(int id)
|
||||||
|
{
|
||||||
|
if (!HasSession("ManageItems")) { return Json(new { success = false }); }
|
||||||
|
|
||||||
|
var item = await db.Items.FindAsync(id);
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
db.Items.Remove(item);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
return Json(new { success = true });
|
||||||
|
}
|
||||||
|
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 { statusModel.Status = "Wrong"; }
|
||||||
}
|
}
|
||||||
else { statusModel.Status = "Block"; }
|
else if (user != null) { statusModel.Status = "Block"; }
|
||||||
}
|
|
||||||
else { statusModel.Status = "NoExist"; }
|
else { statusModel.Status = "NoExist"; }
|
||||||
}
|
}
|
||||||
else { statusModel.Status = "Empty"; }
|
else { statusModel.Status = "Empty"; }
|
||||||
}
|
}
|
||||||
else { statusModel.Status = "NotValid"; }
|
|
||||||
}
|
|
||||||
catch { statusModel.Status = "Error"; }
|
catch { statusModel.Status = "Error"; }
|
||||||
return Json(statusModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("~/Panel/Logout")]
|
return Json(statusModel);
|
||||||
public async Task Logout()
|
|
||||||
{
|
|
||||||
if (Session["User"] != null)
|
|
||||||
{
|
|
||||||
var UserModel = Session["User"] as User;
|
|
||||||
var Single = await db.Users.FindAsync(UserModel.User_Id);
|
|
||||||
if (Single != null)
|
|
||||||
{
|
|
||||||
Single.User_Token = null;
|
|
||||||
await db.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Session.Clear();
|
|
||||||
Session.Abandon();
|
|
||||||
SetCookie("UserId", "", -1);
|
|
||||||
SetCookie("UserToken", "", -1);
|
|
||||||
Response.Redirect("~/Panel/Login");
|
|
||||||
}
|
|
||||||
[Route("~/Login")]
|
|
||||||
[Route("Login")]
|
|
||||||
public async Task<ActionResult> Login(string Return = "")
|
|
||||||
{
|
|
||||||
ViewBag.Return = Return;
|
|
||||||
if (Session["User"] != null)
|
|
||||||
{
|
|
||||||
Response.Redirect("~/panel/index");
|
|
||||||
}
|
|
||||||
else if (UserSessionExists()) { Response.Redirect("~/panel/Index"); }
|
|
||||||
return View();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UserSessionExists()
|
bool UserSessionExists()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string Token = GetCookie("Token");
|
string tokenFromCookie = GetCookie("Token");
|
||||||
decimal.TryParse(GetCookie("UserId"), out decimal UserId);
|
string userIdFromCookie = GetCookie("UserId");
|
||||||
if (!string.IsNullOrEmpty(Token) && UserId != 0)
|
|
||||||
|
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();
|
return false;
|
||||||
if (Single != null)
|
}
|
||||||
|
|
||||||
|
if (!int.TryParse(userIdFromCookie, out int userId))
|
||||||
{
|
{
|
||||||
Session["User"] = Single;
|
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
|
else
|
||||||
{
|
{
|
||||||
SetCookie("Token", "", -1);
|
SetCookie("Token", "", -1);
|
||||||
SetCookie("UserId", "", -1);
|
SetCookie("UserId", "", -1);
|
||||||
}
|
|
||||||
if (Session["User"] != null) { return true; }
|
|
||||||
}
|
|
||||||
SetCookie("Token", "", -1);
|
|
||||||
SetCookie("UserId", "", -1);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch { return false; }
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasSession(string Access = "")
|
bool HasSession(string Access = "")
|
||||||
@ -266,107 +349,92 @@ namespace boilerplate.Controllers
|
|||||||
return string.IsNullOrEmpty(Access) || functions.HasAccess((Session["User"] as User).User_Access, Access);
|
return string.IsNullOrEmpty(Access) || functions.HasAccess((Session["User"] as User).User_Access, Access);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("~/Verify")]
|
[Route("~/Panel/Logout")]
|
||||||
[Route("Verify")]
|
public async Task Logout()
|
||||||
public ActionResult Verify(string Phone = "", string Return = "")
|
{
|
||||||
|
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;
|
ViewBag.Return = Return;
|
||||||
if (Session["User"] != null)
|
if (UserSessionExists()) { Response.Redirect("~/panel/Index"); }
|
||||||
{
|
|
||||||
Response.Redirect("~/Index");
|
|
||||||
}
|
|
||||||
if (Phone == "")
|
|
||||||
{
|
|
||||||
Response.Redirect("~/Login");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ViewBag.Phone = Phone;
|
|
||||||
}
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
//set session and cookies afte login
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Complete")]
|
public ActionResult Complete(int User, string Token)
|
||||||
[Route("~/Complete")]
|
|
||||||
public ActionResult Complete()
|
|
||||||
{
|
{
|
||||||
try
|
var user = db.Users.FirstOrDefault(u => u.User_Id == User && u.User_Token == Token);
|
||||||
|
if (user != null)
|
||||||
{
|
{
|
||||||
// Log query parameters
|
Session["User"] = user;
|
||||||
var user = Request.QueryString["User"];
|
SetCookie("UserId", user.User_Id.ToString());
|
||||||
var token = Request.QueryString["Token"];
|
SetCookie("Token", user.User_Token);
|
||||||
|
return new HttpStatusCodeResult(HttpStatusCode.OK);
|
||||||
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.");
|
|
||||||
}
|
}
|
||||||
|
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
|
||||||
// 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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string SetCookie(string Key, string Value, int ExpireDay = 365)
|
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) });
|
Expires = DateTime.Now.AddDays(ExpireDay),
|
||||||
}
|
Path = "/",
|
||||||
catch { }
|
SameSite = SameSiteMode.Lax
|
||||||
|
};
|
||||||
|
Response.Cookies.Add(cookie);
|
||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetCookie(string Key)
|
string GetCookie(string Key)
|
||||||
{
|
|
||||||
string value = string.Empty;
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var cookie = Request.Cookies[Key];
|
var cookie = Request.Cookies[Key];
|
||||||
if (cookie != null)
|
return cookie?.Value ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<JsonResult> UpdateItem(int id, string newTitle)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(cookie.Value))
|
if (!HasSession("ManageItems")) { return Json(new { success = false, message = "Unauthorized" }); }
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(newTitle))
|
||||||
{
|
{
|
||||||
return value;
|
return Json(new { success = false, message = "نام آیتم نمیتواند خالی باشد." });
|
||||||
}
|
}
|
||||||
value = cookie.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 });
|
||||||
}
|
}
|
||||||
catch { }
|
return Json(new { success = false, message = "آیتم یافت نشد." });
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 boilerplate.Models;
|
||||||
|
using ClosedXML.Excel;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -9,11 +10,13 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Hosting;
|
using System.Web.Hosting;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
|
|
||||||
|
|
||||||
namespace boilerplate.Controllers
|
namespace boilerplate.Controllers
|
||||||
{
|
{
|
||||||
public class UserController : ApiController
|
public class UserController : ApiController
|
||||||
@ -275,6 +278,7 @@ namespace boilerplate.Controllers
|
|||||||
Token = Token,
|
Token = Token,
|
||||||
Id = user.User_Id,
|
Id = user.User_Id,
|
||||||
Phone = user.User_Phone,
|
Phone = user.User_Phone,
|
||||||
|
role = user.User_Role,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -319,5 +323,237 @@ namespace boilerplate.Controllers
|
|||||||
}
|
}
|
||||||
return statusModel;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,6 +13,8 @@ namespace boilerplate
|
|||||||
{
|
{
|
||||||
protected void Application_Start()
|
protected void Application_Start()
|
||||||
{
|
{
|
||||||
|
// خط کد قبلی که باعث خطا میشد، حذف شده است.
|
||||||
|
|
||||||
AreaRegistration.RegisterAllAreas();
|
AreaRegistration.RegisterAllAreas();
|
||||||
GlobalConfiguration.Configure(WebApiConfig.Register);
|
GlobalConfiguration.Configure(WebApiConfig.Register);
|
||||||
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
||||||
|
|||||||
BIN
Media/News/36ff946d-e1c1-4d40-8018-149f3a5e06d8.png
Normal file
|
After Width: | Height: | Size: 695 KiB |
BIN
Media/News/45669dc1-2d99-4dcc-88cb-13651ebc8ce4.jpg
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
Media/News/ffcb03be-514d-4056-8438-e15833ada13c.png
Normal file
|
After Width: | Height: | Size: 695 KiB |
BIN
Media/User/1404_5_22_10_56_20_416_20506.jpg
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
Media/User/1404_5_25_14_30_20_274_38765.png
Normal file
|
After Width: | Height: | Size: 628 KiB |
BIN
Media/User/1404_5_25_15_24_9_560_51457.png
Normal file
|
After Width: | Height: | Size: 628 KiB |
BIN
Media/User/1404_5_25_15_6_1_747_47110.png
Normal file
|
After Width: | Height: | Size: 628 KiB |
BIN
Media/User/dUser.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
24
Models/Client.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated from a template.
|
||||||
|
//
|
||||||
|
// Manual changes to this file may cause unexpected behavior in your application.
|
||||||
|
// Manual changes to this file will be overwritten if the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace boilerplate.Models
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class Client
|
||||||
|
{
|
||||||
|
public int Client_Id { get; set; }
|
||||||
|
public string Client_Name { get; set; }
|
||||||
|
public string Client_LastName { get; set; }
|
||||||
|
public string Client_PhoneNumber { get; set; }
|
||||||
|
public string Client_UserName { get; set; }
|
||||||
|
public string Client_Email { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Models/Item.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated from a template.
|
||||||
|
//
|
||||||
|
// Manual changes to this file may cause unexpected behavior in your application.
|
||||||
|
// Manual changes to this file will be overwritten if the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace boilerplate.Models
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class Item
|
||||||
|
{
|
||||||
|
public int Item_Id { get; set; }
|
||||||
|
public string Item_Title { get; set; }
|
||||||
|
public string Item_Type { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,6 +25,9 @@ namespace boilerplate.Models
|
|||||||
throw new UnintentionalCodeFirstException();
|
throw new UnintentionalCodeFirstException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual DbSet<Client> Clients { get; set; }
|
||||||
|
public virtual DbSet<Item> Items { get; set; }
|
||||||
|
public virtual DbSet<News> News { get; set; }
|
||||||
public virtual DbSet<Setting> Settings { get; set; }
|
public virtual DbSet<Setting> Settings { get; set; }
|
||||||
public virtual DbSet<User> Users { get; set; }
|
public virtual DbSet<User> Users { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
2
Models/Model1.Designer.cs
generated
@ -1,4 +1,4 @@
|
|||||||
// T4 code generation is enabled for model 'D:\Users\l\source\repos\boilerplate\Models\Model1.edmx'.
|
// T4 code generation is enabled for model 'C:\Users\Senat\source\repos\boilerPlate - Test\new-boilerplate\Models\Model1.edmx'.
|
||||||
// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
|
// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
|
||||||
// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
|
// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
|
||||||
// is open in the designer.
|
// is open in the designer.
|
||||||
|
|||||||
@ -5,6 +5,40 @@
|
|||||||
<!-- SSDL content -->
|
<!-- SSDL content -->
|
||||||
<edmx:StorageModels>
|
<edmx:StorageModels>
|
||||||
<Schema Namespace="boilerplateModel.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
|
<Schema Namespace="boilerplateModel.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
|
||||||
|
<EntityType Name="Client">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="Client_Id" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="Client_Id" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
|
||||||
|
<Property Name="Client_Name" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
<Property Name="Client_LastName" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
<Property Name="Client_PhoneNumber" Type="nvarchar" MaxLength="50" Nullable="false" />
|
||||||
|
<Property Name="Client_UserName" Type="nvarchar" MaxLength="50" Nullable="false" />
|
||||||
|
<Property Name="Client_Email" Type="nvarchar" MaxLength="50" Nullable="false" />
|
||||||
|
</EntityType>
|
||||||
|
<EntityType Name="Item">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="Item_Id" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="Item_Id" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
|
||||||
|
<Property Name="Item_Title" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
<Property Name="Item_Type" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
</EntityType>
|
||||||
|
<EntityType Name="News">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="News_ID" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="News_ID" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
|
||||||
|
<Property Name="News_Title" Type="nvarchar" MaxLength="100" Nullable="false" />
|
||||||
|
<Property Name="News_Description" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
<Property Name="News_Summary" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
<Property Name="News_Category" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
<Property Name="News_Tag" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
<Property Name="News_Date" Type="datetime2" Precision="7" Nullable="false" />
|
||||||
|
<Property Name="News_CreateDate" Type="datetime2" Precision="7" Nullable="false" />
|
||||||
|
<Property Name="News_EditDate" Type="datetime2" Precision="7" />
|
||||||
|
<Property Name="News_IMG" Type="nvarchar(max)" Nullable="false" />
|
||||||
|
</EntityType>
|
||||||
<EntityType Name="Setting">
|
<EntityType Name="Setting">
|
||||||
<Key>
|
<Key>
|
||||||
<PropertyRef Name="Setting_Id" />
|
<PropertyRef Name="Setting_Id" />
|
||||||
@ -53,14 +87,57 @@
|
|||||||
<Property Name="User_LoginDateFa" Type="nvarchar" MaxLength="50" />
|
<Property Name="User_LoginDateFa" Type="nvarchar" MaxLength="50" />
|
||||||
</EntityType>
|
</EntityType>
|
||||||
<EntityContainer Name="boilerplateModelStoreContainer">
|
<EntityContainer Name="boilerplateModelStoreContainer">
|
||||||
|
<EntitySet Name="Client" EntityType="Self.Client" Schema="dbo" store:Type="Tables" />
|
||||||
|
<EntitySet Name="Item" EntityType="Self.Item" Schema="dbo" store:Type="Tables" />
|
||||||
|
<EntitySet Name="News" EntityType="Self.News" Schema="dbo" store:Type="Tables" />
|
||||||
<EntitySet Name="Setting" EntityType="Self.Setting" Schema="dbo" store:Type="Tables" />
|
<EntitySet Name="Setting" EntityType="Self.Setting" Schema="dbo" store:Type="Tables" />
|
||||||
<EntitySet Name="User" EntityType="Self.User" Schema="dbo" store:Type="Tables" />
|
<EntitySet Name="User" EntityType="Self.User" Schema="dbo" store:Type="Tables" />
|
||||||
</EntityContainer>
|
</EntityContainer>
|
||||||
</Schema>
|
</Schema></edmx:StorageModels>
|
||||||
</edmx:StorageModels>
|
|
||||||
<!-- CSDL content -->
|
<!-- CSDL content -->
|
||||||
<edmx:ConceptualModels>
|
<edmx:ConceptualModels>
|
||||||
<Schema Namespace="boilerplateModel" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
|
<Schema Namespace="boilerplateModel" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
|
||||||
|
<EntityContainer Name="boilerplateEntities" annotation:LazyLoadingEnabled="true">
|
||||||
|
<EntitySet Name="Clients" EntityType="boilerplateModel.Client" />
|
||||||
|
<EntitySet Name="Items" EntityType="boilerplateModel.Item" />
|
||||||
|
<EntitySet Name="News" EntityType="boilerplateModel.News" />
|
||||||
|
<EntitySet Name="Settings" EntityType="boilerplateModel.Setting" />
|
||||||
|
<EntitySet Name="Users" EntityType="boilerplateModel.User" />
|
||||||
|
</EntityContainer>
|
||||||
|
<EntityType Name="Client">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="Client_Id" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="Client_Id" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
|
||||||
|
<Property Name="Client_Name" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="Client_LastName" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="Client_PhoneNumber" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="Client_UserName" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="Client_Email" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
|
</EntityType>
|
||||||
|
<EntityType Name="Item">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="Item_Id" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="Item_Id" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
|
||||||
|
<Property Name="Item_Title" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="Item_Type" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
</EntityType>
|
||||||
|
<EntityType Name="News">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="News_ID" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="News_ID" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
|
||||||
|
<Property Name="News_Title" Type="String" Nullable="false" MaxLength="100" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="News_Description" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="News_Summary" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="News_Category" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="News_Tag" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
<Property Name="News_Date" Type="DateTime" Nullable="false" Precision="7" />
|
||||||
|
<Property Name="News_CreateDate" Type="DateTime" Nullable="false" Precision="7" />
|
||||||
|
<Property Name="News_EditDate" Type="DateTime" Precision="7" />
|
||||||
|
<Property Name="News_IMG" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
|
</EntityType>
|
||||||
<EntityType Name="Setting">
|
<EntityType Name="Setting">
|
||||||
<Key>
|
<Key>
|
||||||
<PropertyRef Name="Setting_Id" />
|
<PropertyRef Name="Setting_Id" />
|
||||||
@ -94,76 +171,109 @@
|
|||||||
<Property Name="User_Family" Type="String" MaxLength="150" FixedLength="false" Unicode="true" />
|
<Property Name="User_Family" Type="String" MaxLength="150" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_Image" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
|
<Property Name="User_Image" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_NationalCode" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
|
<Property Name="User_NationalCode" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_Phone" Type="String" MaxLength="50" FixedLength="false" Unicode="true" Nullable="false" />
|
<Property Name="User_Phone" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_Password" Type="String" MaxLength="150" FixedLength="false" Unicode="true" />
|
<Property Name="User_Password" Type="String" MaxLength="150" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_Code" Type="Int32" />
|
<Property Name="User_Code" Type="Int32" />
|
||||||
<Property Name="User_Token" Type="String" MaxLength="150" FixedLength="false" Unicode="true" />
|
<Property Name="User_Token" Type="String" MaxLength="150" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_Status" Type="Int32" Nullable="false" />
|
<Property Name="User_Status" Type="Int32" Nullable="false" />
|
||||||
<Property Name="User_Role" Type="String" MaxLength="50" FixedLength="false" Unicode="true" Nullable="false" />
|
<Property Name="User_Role" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_Access" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" Nullable="false" />
|
<Property Name="User_Access" Type="String" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_Email" Type="String" MaxLength="350" FixedLength="false" Unicode="true" />
|
<Property Name="User_Email" Type="String" MaxLength="350" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_Birthday" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
|
<Property Name="User_Birthday" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_CreatedDate" Type="DateTime" Nullable="false" Precision="7" />
|
<Property Name="User_CreatedDate" Type="DateTime" Nullable="false" Precision="7" />
|
||||||
<Property Name="User_CreatedDateFa" Type="String" MaxLength="50" FixedLength="false" Unicode="true" Nullable="false" />
|
<Property Name="User_CreatedDateFa" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
<Property Name="User_LoginDate" Type="DateTime" Precision="7" />
|
<Property Name="User_LoginDate" Type="DateTime" Precision="7" />
|
||||||
<Property Name="User_LoginDateFa" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
|
<Property Name="User_LoginDateFa" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
|
||||||
</EntityType>
|
</EntityType>
|
||||||
<EntityContainer Name="boilerplateEntities" annotation:LazyLoadingEnabled="true">
|
|
||||||
<EntitySet Name="Settings" EntityType="Self.Setting" />
|
|
||||||
<EntitySet Name="Users" EntityType="Self.User" />
|
|
||||||
</EntityContainer>
|
|
||||||
</Schema>
|
</Schema>
|
||||||
</edmx:ConceptualModels>
|
</edmx:ConceptualModels>
|
||||||
<!-- C-S mapping content -->
|
<!-- C-S mapping content -->
|
||||||
<edmx:Mappings>
|
<edmx:Mappings>
|
||||||
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
|
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
|
||||||
<EntityContainerMapping StorageEntityContainer="boilerplateModelStoreContainer" CdmEntityContainer="boilerplateEntities">
|
<EntityContainerMapping StorageEntityContainer="boilerplateModelStoreContainer" CdmEntityContainer="boilerplateEntities">
|
||||||
|
<EntitySetMapping Name="Clients">
|
||||||
|
<EntityTypeMapping TypeName="boilerplateModel.Client">
|
||||||
|
<MappingFragment StoreEntitySet="Client">
|
||||||
|
<ScalarProperty Name="Client_Email" ColumnName="Client_Email" />
|
||||||
|
<ScalarProperty Name="Client_UserName" ColumnName="Client_UserName" />
|
||||||
|
<ScalarProperty Name="Client_PhoneNumber" ColumnName="Client_PhoneNumber" />
|
||||||
|
<ScalarProperty Name="Client_LastName" ColumnName="Client_LastName" />
|
||||||
|
<ScalarProperty Name="Client_Name" ColumnName="Client_Name" />
|
||||||
|
<ScalarProperty Name="Client_Id" ColumnName="Client_Id" />
|
||||||
|
</MappingFragment>
|
||||||
|
</EntityTypeMapping>
|
||||||
|
</EntitySetMapping>
|
||||||
|
<EntitySetMapping Name="Items">
|
||||||
|
<EntityTypeMapping TypeName="boilerplateModel.Item">
|
||||||
|
<MappingFragment StoreEntitySet="Item">
|
||||||
|
<ScalarProperty Name="Item_Type" ColumnName="Item_Type" />
|
||||||
|
<ScalarProperty Name="Item_Title" ColumnName="Item_Title" />
|
||||||
|
<ScalarProperty Name="Item_Id" ColumnName="Item_Id" />
|
||||||
|
</MappingFragment>
|
||||||
|
</EntityTypeMapping>
|
||||||
|
</EntitySetMapping>
|
||||||
|
<EntitySetMapping Name="News">
|
||||||
|
<EntityTypeMapping TypeName="boilerplateModel.News">
|
||||||
|
<MappingFragment StoreEntitySet="News">
|
||||||
|
<ScalarProperty Name="News_IMG" ColumnName="News_IMG" />
|
||||||
|
<ScalarProperty Name="News_EditDate" ColumnName="News_EditDate" />
|
||||||
|
<ScalarProperty Name="News_CreateDate" ColumnName="News_CreateDate" />
|
||||||
|
<ScalarProperty Name="News_Date" ColumnName="News_Date" />
|
||||||
|
<ScalarProperty Name="News_Tag" ColumnName="News_Tag" />
|
||||||
|
<ScalarProperty Name="News_Category" ColumnName="News_Category" />
|
||||||
|
<ScalarProperty Name="News_Summary" ColumnName="News_Summary" />
|
||||||
|
<ScalarProperty Name="News_Description" ColumnName="News_Description" />
|
||||||
|
<ScalarProperty Name="News_Title" ColumnName="News_Title" />
|
||||||
|
<ScalarProperty Name="News_ID" ColumnName="News_ID" />
|
||||||
|
</MappingFragment>
|
||||||
|
</EntityTypeMapping>
|
||||||
|
</EntitySetMapping>
|
||||||
<EntitySetMapping Name="Settings">
|
<EntitySetMapping Name="Settings">
|
||||||
<EntityTypeMapping TypeName="boilerplateModel.Setting">
|
<EntityTypeMapping TypeName="boilerplateModel.Setting">
|
||||||
<MappingFragment StoreEntitySet="Setting">
|
<MappingFragment StoreEntitySet="Setting">
|
||||||
<ScalarProperty Name="Setting_Id" ColumnName="Setting_Id" />
|
|
||||||
<ScalarProperty Name="Setting_Name" ColumnName="Setting_Name" />
|
|
||||||
<ScalarProperty Name="Setting_Title" ColumnName="Setting_Title" />
|
|
||||||
<ScalarProperty Name="Setting_Discount" ColumnName="Setting_Discount" />
|
|
||||||
<ScalarProperty Name="Setting_Description" ColumnName="Setting_Description" />
|
|
||||||
<ScalarProperty Name="Setting_Keywords" ColumnName="Setting_Keywords" />
|
|
||||||
<ScalarProperty Name="Setting_Header" ColumnName="Setting_Header" />
|
|
||||||
<ScalarProperty Name="Setting_Footer" ColumnName="Setting_Footer" />
|
|
||||||
<ScalarProperty Name="Setting_Social" ColumnName="Setting_Social" />
|
|
||||||
<ScalarProperty Name="Setting_Username" ColumnName="Setting_Username" />
|
|
||||||
<ScalarProperty Name="Setting_Password" ColumnName="Setting_Password" />
|
|
||||||
<ScalarProperty Name="Setting_FromNumber" ColumnName="Setting_FromNumber" />
|
|
||||||
<ScalarProperty Name="Setting_Send" ColumnName="Setting_Send" />
|
|
||||||
<ScalarProperty Name="Setting_PaternLogin" ColumnName="Setting_PaternLogin" />
|
|
||||||
<ScalarProperty Name="Setting_Service" ColumnName="Setting_Service" />
|
|
||||||
<ScalarProperty Name="Setting_Address" ColumnName="Setting_Address" />
|
|
||||||
<ScalarProperty Name="Setting_PostCode" ColumnName="Setting_PostCode" />
|
|
||||||
<ScalarProperty Name="Setting_Phone" ColumnName="Setting_Phone" />
|
|
||||||
<ScalarProperty Name="Setting_Website" ColumnName="Setting_Website" />
|
<ScalarProperty Name="Setting_Website" ColumnName="Setting_Website" />
|
||||||
|
<ScalarProperty Name="Setting_Phone" ColumnName="Setting_Phone" />
|
||||||
|
<ScalarProperty Name="Setting_PostCode" ColumnName="Setting_PostCode" />
|
||||||
|
<ScalarProperty Name="Setting_Address" ColumnName="Setting_Address" />
|
||||||
|
<ScalarProperty Name="Setting_Service" ColumnName="Setting_Service" />
|
||||||
|
<ScalarProperty Name="Setting_PaternLogin" ColumnName="Setting_PaternLogin" />
|
||||||
|
<ScalarProperty Name="Setting_Send" ColumnName="Setting_Send" />
|
||||||
|
<ScalarProperty Name="Setting_FromNumber" ColumnName="Setting_FromNumber" />
|
||||||
|
<ScalarProperty Name="Setting_Password" ColumnName="Setting_Password" />
|
||||||
|
<ScalarProperty Name="Setting_Username" ColumnName="Setting_Username" />
|
||||||
|
<ScalarProperty Name="Setting_Social" ColumnName="Setting_Social" />
|
||||||
|
<ScalarProperty Name="Setting_Footer" ColumnName="Setting_Footer" />
|
||||||
|
<ScalarProperty Name="Setting_Header" ColumnName="Setting_Header" />
|
||||||
|
<ScalarProperty Name="Setting_Keywords" ColumnName="Setting_Keywords" />
|
||||||
|
<ScalarProperty Name="Setting_Description" ColumnName="Setting_Description" />
|
||||||
|
<ScalarProperty Name="Setting_Discount" ColumnName="Setting_Discount" />
|
||||||
|
<ScalarProperty Name="Setting_Title" ColumnName="Setting_Title" />
|
||||||
|
<ScalarProperty Name="Setting_Name" ColumnName="Setting_Name" />
|
||||||
|
<ScalarProperty Name="Setting_Id" ColumnName="Setting_Id" />
|
||||||
</MappingFragment>
|
</MappingFragment>
|
||||||
</EntityTypeMapping>
|
</EntityTypeMapping>
|
||||||
</EntitySetMapping>
|
</EntitySetMapping>
|
||||||
<EntitySetMapping Name="Users">
|
<EntitySetMapping Name="Users">
|
||||||
<EntityTypeMapping TypeName="boilerplateModel.User">
|
<EntityTypeMapping TypeName="boilerplateModel.User">
|
||||||
<MappingFragment StoreEntitySet="User">
|
<MappingFragment StoreEntitySet="User">
|
||||||
<ScalarProperty Name="User_Id" ColumnName="User_Id" />
|
|
||||||
<ScalarProperty Name="User_Name" ColumnName="User_Name" />
|
|
||||||
<ScalarProperty Name="User_Family" ColumnName="User_Family" />
|
|
||||||
<ScalarProperty Name="User_Image" ColumnName="User_Image" />
|
|
||||||
<ScalarProperty Name="User_NationalCode" ColumnName="User_NationalCode" />
|
|
||||||
<ScalarProperty Name="User_Phone" ColumnName="User_Phone" />
|
|
||||||
<ScalarProperty Name="User_Password" ColumnName="User_Password" />
|
|
||||||
<ScalarProperty Name="User_Code" ColumnName="User_Code" />
|
|
||||||
<ScalarProperty Name="User_Token" ColumnName="User_Token" />
|
|
||||||
<ScalarProperty Name="User_Status" ColumnName="User_Status" />
|
|
||||||
<ScalarProperty Name="User_Role" ColumnName="User_Role" />
|
|
||||||
<ScalarProperty Name="User_Access" ColumnName="User_Access" />
|
|
||||||
<ScalarProperty Name="User_Email" ColumnName="User_Email" />
|
|
||||||
<ScalarProperty Name="User_Birthday" ColumnName="User_Birthday" />
|
|
||||||
<ScalarProperty Name="User_CreatedDate" ColumnName="User_CreatedDate" />
|
|
||||||
<ScalarProperty Name="User_CreatedDateFa" ColumnName="User_CreatedDateFa" />
|
|
||||||
<ScalarProperty Name="User_LoginDate" ColumnName="User_LoginDate" />
|
|
||||||
<ScalarProperty Name="User_LoginDateFa" ColumnName="User_LoginDateFa" />
|
<ScalarProperty Name="User_LoginDateFa" ColumnName="User_LoginDateFa" />
|
||||||
|
<ScalarProperty Name="User_LoginDate" ColumnName="User_LoginDate" />
|
||||||
|
<ScalarProperty Name="User_CreatedDateFa" ColumnName="User_CreatedDateFa" />
|
||||||
|
<ScalarProperty Name="User_CreatedDate" ColumnName="User_CreatedDate" />
|
||||||
|
<ScalarProperty Name="User_Birthday" ColumnName="User_Birthday" />
|
||||||
|
<ScalarProperty Name="User_Email" ColumnName="User_Email" />
|
||||||
|
<ScalarProperty Name="User_Access" ColumnName="User_Access" />
|
||||||
|
<ScalarProperty Name="User_Role" ColumnName="User_Role" />
|
||||||
|
<ScalarProperty Name="User_Status" ColumnName="User_Status" />
|
||||||
|
<ScalarProperty Name="User_Token" ColumnName="User_Token" />
|
||||||
|
<ScalarProperty Name="User_Code" ColumnName="User_Code" />
|
||||||
|
<ScalarProperty Name="User_Password" ColumnName="User_Password" />
|
||||||
|
<ScalarProperty Name="User_Phone" ColumnName="User_Phone" />
|
||||||
|
<ScalarProperty Name="User_NationalCode" ColumnName="User_NationalCode" />
|
||||||
|
<ScalarProperty Name="User_Image" ColumnName="User_Image" />
|
||||||
|
<ScalarProperty Name="User_Family" ColumnName="User_Family" />
|
||||||
|
<ScalarProperty Name="User_Name" ColumnName="User_Name" />
|
||||||
|
<ScalarProperty Name="User_Id" ColumnName="User_Id" />
|
||||||
</MappingFragment>
|
</MappingFragment>
|
||||||
</EntityTypeMapping>
|
</EntityTypeMapping>
|
||||||
</EntitySetMapping>
|
</EntitySetMapping>
|
||||||
|
|||||||
@ -5,8 +5,11 @@
|
|||||||
<!-- Diagram content (shape and connector positions) -->
|
<!-- Diagram content (shape and connector positions) -->
|
||||||
<edmx:Diagrams>
|
<edmx:Diagrams>
|
||||||
<Diagram DiagramId="da0c6095014e4dcdba4918743ea7998d" Name="Diagram1">
|
<Diagram DiagramId="da0c6095014e4dcdba4918743ea7998d" Name="Diagram1">
|
||||||
<EntityTypeShape EntityType="boilerplateModel.Setting" Width="1.5" PointX="0.75" PointY="0.75" IsExpanded="true" />
|
<EntityTypeShape EntityType="boilerplateModel.Client" Width="1.5" PointX="0.75" PointY="0.75" />
|
||||||
<EntityTypeShape EntityType="boilerplateModel.User" Width="1.5" PointX="2.75" PointY="0.75" IsExpanded="true" />
|
<EntityTypeShape EntityType="boilerplateModel.Item" Width="1.5" PointX="2.75" PointY="0.75" />
|
||||||
|
<EntityTypeShape EntityType="boilerplateModel.News" Width="1.5" PointX="8.75" PointY="0.75" />
|
||||||
|
<EntityTypeShape EntityType="boilerplateModel.Setting" Width="1.5" PointX="6.75" PointY="0.75" />
|
||||||
|
<EntityTypeShape EntityType="boilerplateModel.User" Width="1.5" PointX="4.75" PointY="0.75" />
|
||||||
</Diagram>
|
</Diagram>
|
||||||
</edmx:Diagrams>
|
</edmx:Diagrams>
|
||||||
</edmx:Designer>
|
</edmx:Designer>
|
||||||
|
|||||||
28
Models/News.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated from a template.
|
||||||
|
//
|
||||||
|
// Manual changes to this file may cause unexpected behavior in your application.
|
||||||
|
// Manual changes to this file will be overwritten if the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace boilerplate.Models
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class News
|
||||||
|
{
|
||||||
|
public int News_ID { get; set; }
|
||||||
|
public string News_Title { get; set; }
|
||||||
|
public string News_Description { get; set; }
|
||||||
|
public string News_Summary { get; set; }
|
||||||
|
public string News_Category { get; set; }
|
||||||
|
public string News_Tag { get; set; }
|
||||||
|
public System.DateTime News_Date { get; set; }
|
||||||
|
public System.DateTime News_CreateDate { get; set; }
|
||||||
|
public Nullable<System.DateTime> News_EditDate { get; set; }
|
||||||
|
public string News_IMG { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
41
Models/NewsModel.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
namespace boilerplate.Models
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
|
||||||
|
// This is the metadata class where we define display names and validation rules.
|
||||||
|
public class NewsMetadata
|
||||||
|
{
|
||||||
|
[Display(Name = "عنوان خبر")]
|
||||||
|
[Required(ErrorMessage = "لطفاً عنوان خبر را وارد کنید.")]
|
||||||
|
public string News_Title { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "توضیحات کامل")]
|
||||||
|
[AllowHtml]
|
||||||
|
[Required(ErrorMessage = "لطفاً توضیحات خبر را وارد کنید.")]
|
||||||
|
public string News_Description { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "خلاصه خبر")]
|
||||||
|
public string News_Summary { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "دسته بندی")]
|
||||||
|
public string News_Category { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "تگها")]
|
||||||
|
public string News_Tag { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "تاریخ نمایش")]
|
||||||
|
public Nullable<System.DateTime> News_Date { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "تصویر شاخص")]
|
||||||
|
public string News_IMG { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[MetadataType(typeof(NewsMetadata))]
|
||||||
|
public partial class News
|
||||||
|
{
|
||||||
|
// This part remains empty.
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,5 +6,7 @@
|
|||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public string Result { get; set; }
|
public string Result { get; set; }
|
||||||
public string FileContent { get; set; }
|
public string FileContent { get; set; }
|
||||||
|
|
||||||
|
public string RedirectUrl { get; set; } // این خط رو به کلاس اضافه کن
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
83
Views/Home/AllNews.cshtml
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
@model IEnumerable<boilerplate.Models.News>
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewBag.Title = "آخرین اخبار";
|
||||||
|
|
||||||
|
}
|
||||||
|
<style>
|
||||||
|
.badge-info {
|
||||||
|
color: black;
|
||||||
|
border: 1px solid lightgray;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
padding-top:0px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="container mt-5">
|
||||||
|
<h2 class="text-center mb-4">@ViewBag.Title</h2>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
@if (!Model.Any())
|
||||||
|
{
|
||||||
|
<div class="col-12">
|
||||||
|
<p class="alert alert-warning text-center">در حال حاضر خبری برای نمایش وجود ندارد.</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var item in Model)
|
||||||
|
{
|
||||||
|
<div class="col-md-4 mb-4">
|
||||||
|
<div class="card h-100 shadow-sm">
|
||||||
|
<img src="@Url.Content("~/Media/News/" + item.News_IMG)" class="card-img-top" alt="@item.News_Title" style="height: 200px; object-fit: cover;"
|
||||||
|
onerror="this.onerror=null;this.src='@Url.Content("~/Media/default-image.png")';">
|
||||||
|
<div class="card-body d-flex flex-column">
|
||||||
|
<h5 class="card-title">@item.News_Title</h5>
|
||||||
|
|
||||||
|
<p class="card-text text-muted">@item.News_Summary</p>
|
||||||
|
|
||||||
|
@* --- New section for Category and Tags --- *@
|
||||||
|
<div class="mt-3">
|
||||||
|
@if (!string.IsNullOrEmpty(item.News_Category))
|
||||||
|
{
|
||||||
|
<div class="mb-2">
|
||||||
|
<strong style="font-size: 0.9rem;">دسته بندی: </strong>
|
||||||
|
@* --- FIXED: Loop through categories to create separate badges --- *@
|
||||||
|
@{
|
||||||
|
var categories = item.News_Category.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
foreach (var category in categories)
|
||||||
|
{
|
||||||
|
<span class="badge badge-info p-2 mr-1">@category.Trim()</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (!string.IsNullOrEmpty(item.News_Tag))
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<strong style="font-size: 0.9rem;">تگ ها: </strong>
|
||||||
|
@{
|
||||||
|
var tags = item.News_Tag.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
foreach (var tag in tags)
|
||||||
|
{
|
||||||
|
<span class="badge badge-light p-2 mr-1" style="color: #333; border: 1px solid #ccc;">@tag.Trim()</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@*<div class="mt-auto pt-3">
|
||||||
|
<a href="@Url.Action("NewsDetails", "Home", new { id = item.News_ID })" class="btn btn-primary">ادامه مطلب</a>
|
||||||
|
</div>*@
|
||||||
|
</div>
|
||||||
|
<div class="card-footer text-muted small">
|
||||||
|
@(item.News_Date > DateTime.MinValue ? new boilerplate.Models.Functions().ConvertToPersianDate(item.News_Date) : "")
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
116
Views/Panel/AddNews.cshtml
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
@model boilerplate.Controllers.PanelController.AddNewsViewModel
|
||||||
|
@{
|
||||||
|
ViewBag.Title = Model.News.News_ID == 0 ? "افزودن خبر جدید" : "ویرایش خبر";
|
||||||
|
Layout = "~/Views/_PanelSideBar.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Heads {
|
||||||
|
<!-- Add CSS for Select2 library -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
||||||
|
<script src="https://cdn.ckeditor.com/4.16.2/standard/ckeditor.js"></script>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="card card-custom">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-label">@ViewBag.Title</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@using (Html.BeginForm("AddNews", "Panel", FormMethod.Post, new { enctype = "multipart/form-data" }))
|
||||||
|
{
|
||||||
|
@Html.AntiForgeryToken()
|
||||||
|
@Html.HiddenFor(model => model.News.News_ID)
|
||||||
|
@Html.HiddenFor(model => model.News.News_IMG)
|
||||||
|
|
||||||
|
if (!ViewData.ModelState.IsValid)
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
@Html.ValidationSummary(false)
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>عنوان خبر</label>
|
||||||
|
@Html.EditorFor(model => model.News.News_Title, new { htmlAttributes = new { @class = "form-control" } })
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>دستهبندیها</label>
|
||||||
|
<select name="selectedCategories" class="form-control select2-categories" multiple="multiple">
|
||||||
|
@{
|
||||||
|
var selectedCategories = (Model.News.News_Category ?? "").Split(',');
|
||||||
|
}
|
||||||
|
@foreach (var category in Model.AllCategories)
|
||||||
|
{
|
||||||
|
<option value="@category.Item_Title" @(selectedCategories.Contains(category.Item_Title) ? "selected" : "")>@category.Item_Title</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>تگها</label>
|
||||||
|
<select name="selectedTags" class="form-control select2-tags" multiple="multiple">
|
||||||
|
@{
|
||||||
|
var selectedTags = (Model.News.News_Tag ?? "").Split(',');
|
||||||
|
}
|
||||||
|
@foreach (var tag in Model.AllTags)
|
||||||
|
{
|
||||||
|
<option value="@tag.Item_Title" @(selectedTags.Contains(tag.Item_Title) ? "selected" : "")>@tag.Item_Title</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>خلاصه خبر</label>
|
||||||
|
@Html.TextAreaFor(model => model.News.News_Summary, new { @class = "form-control", rows = 3 })
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>توضیحات کامل</label>
|
||||||
|
@Html.TextAreaFor(model => model.News.News_Description, new { @class = "form-control", id = "newsDescriptionEditor" })
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>تصویر شاخص خبر</label>
|
||||||
|
<input type="file" name="imageFile" class="form-control-file" accept="image/*" />
|
||||||
|
@if (!string.IsNullOrEmpty(Model.News.News_IMG))
|
||||||
|
{
|
||||||
|
<div class="mt-2">
|
||||||
|
<span>تصویر فعلی:</span>
|
||||||
|
<img src="~/Media/News/@Model.News.News_IMG" style="width: 150px; height: auto;" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer text-right">
|
||||||
|
<button type="submit" class="btn btn-primary mr-2">ذخیره</button>
|
||||||
|
<a href="@Url.Action("NewsList", "Panel")" class="btn btn-secondary">انصراف</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Script {
|
||||||
|
<!-- کتابخانه Select2 (فرض بر این است که jQuery در لایوت اصلی شما لود شده است) -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
// --- FIXED: Separate initialization for Categories and Tags ---
|
||||||
|
|
||||||
|
// Initialize Select2 for CATEGORIES (without the ability to add new ones)
|
||||||
|
$('.select2-categories').select2({
|
||||||
|
placeholder: "یک یا چند دسته بندی انتخاب کنید",
|
||||||
|
dir: "rtl"
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize Select2 for TAGS (NOW also without the ability to add new ones)
|
||||||
|
$('.select2-tags').select2({
|
||||||
|
placeholder: "یک یا چند تگ انتخاب کنید",
|
||||||
|
dir: "rtl"
|
||||||
|
// The 'tags: true' option has been removed
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize CKEditor
|
||||||
|
CKEDITOR.replace('newsDescriptionEditor', { language: 'fa' });
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
300
Views/Panel/ClientManagement.cshtml
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
@model IEnumerable<boilerplate.Models.Client>
|
||||||
|
@{
|
||||||
|
ViewBag.Title = "مدیریت مشتریان";
|
||||||
|
Layout = "~/Views/_PanelSideBar.cshtml";
|
||||||
|
var currentUser = Session["User"] as boilerplate.Models.User;
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="card card-custom">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">@ViewBag.Title</h3>
|
||||||
|
<div class="card-toolbar">
|
||||||
|
<button type="button" class="btn btn-success font-weight-bolder mr-2" onclick="exportClients(event)">
|
||||||
|
<i class="fa fa-file-excel"></i>
|
||||||
|
خروجی اکسل
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-primary font-weight-bolder" data-toggle="modal" data-target="#importModal">
|
||||||
|
<i class="fa fa-file-import"></i>
|
||||||
|
ورود از اکسل
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>نام</th>
|
||||||
|
<th>نام خانوادگی</th>
|
||||||
|
<th>شماره تلفن</th>
|
||||||
|
<th>نام کاربری</th>
|
||||||
|
<th>ایمیل</th>
|
||||||
|
<th>عملیات</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var client in Model)
|
||||||
|
{
|
||||||
|
<tr id="client-row-@client.Client_Id">
|
||||||
|
<td data-prop="Client_Name">@client.Client_Name</td>
|
||||||
|
<td data-prop="Client_LastName">@client.Client_LastName</td>
|
||||||
|
<td data-prop="Client_PhoneNumber">@client.Client_PhoneNumber</td>
|
||||||
|
<td data-prop="Client_UserName">@client.Client_UserName</td>
|
||||||
|
<td data-prop="Client_Email">@client.Client_Email</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-sm btn-clean btn-icon" title="ویرایش" onclick="openEditModal(@client.Client_Id)">
|
||||||
|
<i class="fa fa-edit text-primary"></i>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-sm btn-clean btn-icon" title="حذف" onclick="deleteClient(@client.Client_Id)">
|
||||||
|
<i class="fa fa-trash text-danger"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal for Excel Upload -->
|
||||||
|
<div class="modal fade" id="importModal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">ورود مشتریان از فایل اکسل</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>فایل اکسل خود را انتخاب کنید. ستونها باید به ترتیب زیر باشند: نام، نام خانوادگی، شماره تلفن، نام کاربری، ایمیل.</p>
|
||||||
|
<input type="file" id="excelFileInput" class="form-control-file" accept=".xlsx" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">انصراف</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="importButton" onclick="importClients(event)">بارگذاری</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- *** ADDED: Modal for Editing a Client *** -->
|
||||||
|
<div class="modal fade" id="editClientModal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">ویرایش اطلاعات مشتری</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="editClientForm">
|
||||||
|
<input type="hidden" id="editClientId" />
|
||||||
|
<div class="form-group">
|
||||||
|
<label>نام</label>
|
||||||
|
<input type="text" id="editClientName" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>نام خانوادگی</label>
|
||||||
|
<input type="text" id="editClientLastName" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>شماره تلفن</label>
|
||||||
|
<input type="text" id="editClientPhone" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>نام کاربری</label>
|
||||||
|
<input type="text" id="editClientUsername" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>ایمیل</label>
|
||||||
|
<input type="email" id="editClientEmail" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">انصراف</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="saveChangesBtn" onclick="saveChanges()">ذخیره تغییرات</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@section Script {
|
||||||
|
<script>
|
||||||
|
const authData = {
|
||||||
|
UserId: @(currentUser?.User_Id ?? 0),
|
||||||
|
Token: "@(currentUser?.User_Token ?? "")"
|
||||||
|
};
|
||||||
|
|
||||||
|
// *** FIXED: Re-added the full logic for importClients ***
|
||||||
|
function importClients(event) {
|
||||||
|
const fileInput = document.getElementById('excelFileInput');
|
||||||
|
if (fileInput.files.length === 0) {
|
||||||
|
toastr.error("لطفاً یک فایل اکسل انتخاب کنید.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("Auth", JSON.stringify(authData));
|
||||||
|
formData.append("ExcelFile", fileInput.files[0]);
|
||||||
|
|
||||||
|
const importBtn = event.target;
|
||||||
|
importBtn.disabled = true;
|
||||||
|
importBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> در حال بارگذاری...';
|
||||||
|
|
||||||
|
fetch('/api/Client/Import', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.Status === "Success") {
|
||||||
|
toastr.success(data.Message || "فایل با موفقیت بارگذاری شد.");
|
||||||
|
setTimeout(() => location.reload(), 2000);
|
||||||
|
} else {
|
||||||
|
toastr.error("خطا در بارگذاری فایل: " + (data.Message || data.Status));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
toastr.error("خطا در برقراری ارتباط با سرور.");
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
importBtn.disabled = false;
|
||||||
|
importBtn.innerHTML = 'بارگذاری';
|
||||||
|
$('#importModal').modal('hide');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** FIXED: Re-added the full logic for exportClients ***
|
||||||
|
function exportClients(event) {
|
||||||
|
const exportBtn = event.target;
|
||||||
|
exportBtn.disabled = true;
|
||||||
|
exportBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> در حال آماده سازی...';
|
||||||
|
|
||||||
|
fetch('/api/Client/Export', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(authData)
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) return response.blob();
|
||||||
|
throw new Error('Network response was not ok.');
|
||||||
|
})
|
||||||
|
.then(blob => {
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.style.display = 'none';
|
||||||
|
a.href = url;
|
||||||
|
a.download = `Clients_${new Date().toISOString().slice(0, 10)}.xlsx`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
toastr.success("فایل اکسل آماده دانلود است.");
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
toastr.error("خطا در ساخت فایل اکسل.");
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
exportBtn.disabled = false;
|
||||||
|
exportBtn.innerHTML = '<i class="fa fa-file-excel"></i> خروجی اکسل';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to open the edit modal and fetch client data
|
||||||
|
function openEditModal(clientId) {
|
||||||
|
fetch(`/api/Client/Get/${clientId}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(authData)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(client => {
|
||||||
|
$('#editClientId').val(client.Client_Id);
|
||||||
|
$('#editClientName').val(client.Client_Name);
|
||||||
|
$('#editClientLastName').val(client.Client_LastName);
|
||||||
|
$('#editClientPhone').val(client.Client_PhoneNumber);
|
||||||
|
$('#editClientUsername').val(client.Client_UserName);
|
||||||
|
$('#editClientEmail').val(client.Client_Email);
|
||||||
|
|
||||||
|
$('#editClientModal').modal('show');
|
||||||
|
})
|
||||||
|
.catch(error => toastr.error("خطا در دریافت اطلاعات مشتری."));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to save the changes from the edit modal
|
||||||
|
function saveChanges() {
|
||||||
|
const saveBtn = document.getElementById('saveChangesBtn');
|
||||||
|
saveBtn.disabled = true;
|
||||||
|
saveBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> در حال ذخیره...';
|
||||||
|
|
||||||
|
const clientData = {
|
||||||
|
Client_Id: parseInt($('#editClientId').val()),
|
||||||
|
Client_Name: $('#editClientName').val(),
|
||||||
|
Client_LastName: $('#editClientLastName').val(),
|
||||||
|
Client_PhoneNumber: $('#editClientPhone').val(),
|
||||||
|
Client_UserName: $('#editClientUsername').val(),
|
||||||
|
Client_Email: $('#editClientEmail').val()
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateModel = {
|
||||||
|
Auth: authData,
|
||||||
|
Client: clientData
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch('/api/Client/Update', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(updateModel)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.Status === "Success") {
|
||||||
|
toastr.success("اطلاعات مشتری با موفقیت ویرایش شد.");
|
||||||
|
const row = $(`#client-row-${clientData.Client_Id}`);
|
||||||
|
row.find('[data-prop="Client_Name"]').text(clientData.Client_Name);
|
||||||
|
row.find('[data-prop="Client_LastName"]').text(clientData.Client_LastName);
|
||||||
|
row.find('[data-prop="Client_PhoneNumber"]').text(clientData.Client_PhoneNumber);
|
||||||
|
row.find('[data-prop="Client_UserName"]').text(clientData.Client_UserName);
|
||||||
|
row.find('[data-prop="Client_Email"]').text(clientData.Client_Email);
|
||||||
|
$('#editClientModal').modal('hide');
|
||||||
|
} else {
|
||||||
|
toastr.error("خطا در ویرایش: " + (data.Message || data.Status));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => toastr.error("خطا در برقراری ارتباط با سرور."))
|
||||||
|
.finally(() => {
|
||||||
|
saveBtn.disabled = false;
|
||||||
|
saveBtn.innerHTML = 'ذخیره تغییرات';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// JavaScript function to delete a client
|
||||||
|
function deleteClient(clientId) {
|
||||||
|
if (!confirm("آیا از حذف این مشتری مطمئن هستید؟")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteAuthData = { ...authData, Id: clientId };
|
||||||
|
|
||||||
|
fetch('/api/Client/Delete', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(deleteAuthData)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.Status === "Success") {
|
||||||
|
toastr.success("مشتری با موفقیت حذف شد.");
|
||||||
|
$("#client-row-" + clientId).fadeOut(500, function() { $(this).remove(); });
|
||||||
|
} else {
|
||||||
|
toastr.error("خطا در حذف مشتری: " + (data.Message || data.Status));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
toastr.error("خطا در برقراری ارتباط با سرور.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
}
|
||||||
@ -70,22 +70,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 form-group">
|
@*<div class="col-lg-6 form-group">
|
||||||
<div class="card card-custom wave wave-animate-slow wave-primary mb-8 mb-lg-0">
|
<div class="card card-custom wave wave-animate-slow wave-primary mb-8 mb-lg-0" style="height:144px;">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex align-items-center p-5">
|
<div class="d-flex align-items-center p-5">
|
||||||
<div class="mr-6">
|
<div class="mr-6">
|
||||||
<i class="fa fa-comments text-primary icon-3x"></i>
|
<i class="fa fa-comments text-primary icon-3x"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-column">
|
<div class="d-flex flex-column">
|
||||||
<a href="~/panel/Chats" class="text-gray text-hover-primary font-weight-bold font-size-h4 mb-3">
|
<a href="" class="text-gray text-hover-primary font-weight-bold font-size-h4 mb-3">
|
||||||
تالار گفتگو
|
تالار گفتگو
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>*@
|
||||||
@*<div class="col-lg-4 form-group">
|
@*<div class="col-lg-4 form-group">
|
||||||
<div class="card card-custom wave wave-animate-slow wave-primary mb-8 mb-lg-0">
|
<div class="card card-custom wave wave-animate-slow wave-primary mb-8 mb-lg-0">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -118,6 +118,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-lg-6 form-group">
|
||||||
|
<div class="card card-custom wave wave-animate-slow wave-primary mb-8 mb-lg-0">
|
||||||
|
<div class="card-body" style="height:143px;">
|
||||||
|
<div class="d-flex align-items-center p-5">
|
||||||
|
<div class="mr-6">
|
||||||
|
<i class="fa fa-newspaper text-primary icon-3x"></i>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-column">
|
||||||
|
<a href="~/panel/NewsList" class="text-gray text-hover-primary font-weight-bold font-size-h4 mb-3">مدیریت اخبار</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -128,4 +143,5 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@section Script{
|
@section Script{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
122
Views/Panel/Items.cshtml
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
@model IEnumerable<boilerplate.Models.Item>
|
||||||
|
@{
|
||||||
|
ViewBag.Title = ViewBag.PageTitle;
|
||||||
|
Layout = "~/Views/_PanelSideBar.cshtml";
|
||||||
|
var itemType = (int)ViewBag.ItemType;
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Add New Item Form -->
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="card card-custom">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">افزودن آیتم جدید</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@using (Html.BeginForm("AddItem", "Panel", FormMethod.Post))
|
||||||
|
{
|
||||||
|
@Html.AntiForgeryToken()
|
||||||
|
@Html.Hidden("Item_Type", itemType)
|
||||||
|
<div class="form-group">
|
||||||
|
<label>@ViewBag.NewItemLabel</label>
|
||||||
|
<input type="text" name="Item_Title" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">افزودن</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- List of Existing Items -->
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="card card-custom">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">@ViewBag.PageTitle</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>نام</th>
|
||||||
|
<th style="width: 120px;">عملیات</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var item in Model)
|
||||||
|
{
|
||||||
|
<tr id="item-@item.Item_Id">
|
||||||
|
<td>
|
||||||
|
<span id="title-text-@item.Item_Id">@item.Item_Title</span>
|
||||||
|
<input type="text" id="title-input-@item.Item_Id" class="form-control d-none" value="@item.Item_Title" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-sm btn-clean btn-icon" title="ویرایش" id="edit-btn-@item.Item_Id" onclick="editItem(@item.Item_Id)">
|
||||||
|
<i class="fa fa-edit text-primary"></i>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-sm btn-clean btn-icon d-none" title="ذخیره" id="save-btn-@item.Item_Id" onclick="saveItem(@item.Item_Id)">
|
||||||
|
<i class="fa fa-save text-success"></i>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-sm btn-clean btn-icon" title="حذف" onclick="deleteItem(@item.Item_Id)">
|
||||||
|
<i class="fa fa-trash text-danger"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Script {
|
||||||
|
<script>
|
||||||
|
function editItem(id) {
|
||||||
|
// مخفی کردن متن و نمایش کادر ویرایش
|
||||||
|
$('#title-text-' + id).addClass('d-none');
|
||||||
|
$('#title-input-' + id).removeClass('d-none').focus();
|
||||||
|
|
||||||
|
// مخفی کردن دکمه ویرایش و نمایش دکمه ذخیره
|
||||||
|
$('#edit-btn-' + id).addClass('d-none');
|
||||||
|
$('#save-btn-' + id).removeClass('d-none');
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveItem(id) {
|
||||||
|
var newTitle = $('#title-input-' + id).val();
|
||||||
|
|
||||||
|
if (!newTitle.trim()) {
|
||||||
|
toastr.error("نام نمی تواند خالی باشد.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.post("@Url.Action("UpdateItem", "Panel")", { id: id, newTitle: newTitle }, function(data) {
|
||||||
|
if (data.success) {
|
||||||
|
// آپدیت متن و بازگشت به حالت نمایش
|
||||||
|
$('#title-text-' + id).text(newTitle).removeClass('d-none');
|
||||||
|
$('#title-input-' + id).addClass('d-none');
|
||||||
|
|
||||||
|
$('#edit-btn-' + id).removeClass('d-none');
|
||||||
|
$('#save-btn-' + id).addClass('d-none');
|
||||||
|
toastr.success("آیتم با موفقیت ویرایش شد.");
|
||||||
|
} else {
|
||||||
|
toastr.error("خطا در ویرایش: " + (data.message || ""));
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
toastr.error("خطا در برقراری ارتباط با سرور.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteItem(id) {
|
||||||
|
if (confirm("آیا از حذف این آیتم مطمئن هستید؟")) {
|
||||||
|
$.post("@Url.Action("DeleteItem", "Panel")", { id: id }, function(data) {
|
||||||
|
if (data.success) {
|
||||||
|
$("#item-" + id).fadeOut();
|
||||||
|
toastr.success("آیتم با موفقیت حذف شد.");
|
||||||
|
} else {
|
||||||
|
toastr.error("خطا در حذف آیتم.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
}
|
||||||
@ -128,7 +128,12 @@
|
|||||||
toastr.success('ورود با موفقیت انجام شد !!!');
|
toastr.success('ورود با موفقیت انجام شد !!!');
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
if (Return == '') {
|
if (Return == '') {
|
||||||
|
if (data.role == 'Admin') {
|
||||||
location.href = "Index";
|
location.href = "Index";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
location.href = '@Url.Action("AllNews", "Home")';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
location.href = Return;
|
location.href = Return;
|
||||||
}
|
}
|
||||||
@ -150,7 +155,6 @@
|
|||||||
}).always(function () {
|
}).always(function () {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
toastr.error('کد تایید را وارد کنید.');
|
toastr.error('کد تایید را وارد کنید.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
77
Views/Panel/NewsList.cshtml
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
@model IEnumerable<boilerplate.Models.News>
|
||||||
|
@{
|
||||||
|
ViewBag.Title = "لیست اخبار";
|
||||||
|
Layout = "~/Views/_PanelSideBar.cshtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="card card-custom">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="card-title">
|
||||||
|
<h3 class="card-label">@ViewBag.Title</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-toolbar">
|
||||||
|
<a href="@Url.Action("AddNews", "Panel")" class="btn btn-primary font-weight-bolder">
|
||||||
|
<i class="fa fa-plus"></i>
|
||||||
|
افزودن خبر جدید
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>تصویر</th>
|
||||||
|
<th>عنوان خبر</th>
|
||||||
|
<th>خلاصه</th>
|
||||||
|
<th>تاریخ ایجاد</th>
|
||||||
|
<th>عملیات</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var item in Model)
|
||||||
|
{
|
||||||
|
<tr id="news-row-@item.News_ID">
|
||||||
|
<td>
|
||||||
|
<img src="~/Media/News/@item.News_IMG" alt="News Image" style="width: 100px; height: auto; border-radius: 8px;"
|
||||||
|
onerror="this.onerror=null;this.src='/Media/default-image.png';" />
|
||||||
|
</td>
|
||||||
|
<td>@item.News_Title</td>
|
||||||
|
<td>@item.News_Summary</td>
|
||||||
|
<td>
|
||||||
|
@(item.News_CreateDate > DateTime.MinValue ? new boilerplate.Models.Functions().ConvertToPersianDate(item.News_CreateDate) : "")
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="@Url.Action("AddNews", "Panel", new { id = item.News_ID })" class="btn btn-sm btn-clean btn-icon" title="ویرایش">
|
||||||
|
<i class="fa fa-edit text-primary"></i>
|
||||||
|
</a>
|
||||||
|
<button class="btn btn-sm btn-clean btn-icon" title="حذف" onclick="deleteNews(@item.News_ID)">
|
||||||
|
<i class="fa fa-trash text-danger"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Script {
|
||||||
|
<script>
|
||||||
|
function deleteNews(id) {
|
||||||
|
if (confirm("آیا از حذف این خبر مطمئن هستید؟ این عملیات قابل بازگشت نیست.")) {
|
||||||
|
$.post("@Url.Action("DeleteNews", "Panel")", { id: id }, function(data) {
|
||||||
|
if (data.success) {
|
||||||
|
$("#news-row-" + id).fadeOut(500, function() { $(this).remove(); });
|
||||||
|
toastr.success("خبر با موفقیت حذف شد.");
|
||||||
|
} else {
|
||||||
|
toastr.error("خطا در حذف خبر. " + (data.message || ""));
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
toastr.error("خطا در برقراری ارتباط با سرور.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
}
|
||||||
@ -6,7 +6,6 @@
|
|||||||
ViewBag.Title = Model.User_Id == 0 ? "کاربر جدید" : Model.User_Name + " " + Model.User_Family;
|
ViewBag.Title = Model.User_Id == 0 ? "کاربر جدید" : Model.User_Name + " " + Model.User_Family;
|
||||||
Layout = "~/Views/_PanelSideBar.cshtml";
|
Layout = "~/Views/_PanelSideBar.cshtml";
|
||||||
Functions functions = new Functions();
|
Functions functions = new Functions();
|
||||||
|
|
||||||
}
|
}
|
||||||
<form autocomplete="off">
|
<form autocomplete="off">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -165,6 +164,13 @@
|
|||||||
تنظیمات
|
تنظیمات
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="checkbox-list mb-3">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" name="chkAccess" value="ManageItems" @(Model.User_Access != null && Model.User_Access.Contains("ManageItems") ? "checked" : "") />
|
||||||
|
<span></span>
|
||||||
|
مدیریت دستهبندی و تگ
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -219,6 +225,14 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
function Save() {
|
function Save() {
|
||||||
|
// --- ADDED: Client-side validation for image on new users ---
|
||||||
|
var isNew = (Id === 0);
|
||||||
|
var fileInput = $("#fuImage")[0];
|
||||||
|
if (isNew && fileInput.files.length === 0) {
|
||||||
|
toastr.error("لطفاً یک تصویر برای کاربر انتخاب کنید.");
|
||||||
|
return; // Stop the function if image is missing
|
||||||
|
}
|
||||||
|
|
||||||
let Phone = $("#txtPhone").val().trim();
|
let Phone = $("#txtPhone").val().trim();
|
||||||
if (Phone.length) {
|
if (Phone.length) {
|
||||||
let Access = "";
|
let Access = "";
|
||||||
@ -238,7 +252,7 @@
|
|||||||
$("#btnSave").css("opacity", 0.5);
|
$("#btnSave").css("opacity", 0.5);
|
||||||
$("#btnSave").attr("onclick", "");
|
$("#btnSave").attr("onclick", "");
|
||||||
let model = {
|
let model = {
|
||||||
Auth: { UserId: UserId, Token: Token },
|
Auth: { UserId: @User.User_Id, Token: "@User.User_Token" },
|
||||||
Id: Id,
|
Id: Id,
|
||||||
Name: $("#txtName").val().trim(),
|
Name: $("#txtName").val().trim(),
|
||||||
Family: $("#txtFamily").val().trim(),
|
Family: $("#txtFamily").val().trim(),
|
||||||
@ -255,12 +269,18 @@
|
|||||||
ajax.addEventListener("load", function (event) {
|
ajax.addEventListener("load", function (event) {
|
||||||
$("#btnSave").css("opacity", 1);
|
$("#btnSave").css("opacity", 1);
|
||||||
let data = JSON.parse(event.target.responseText);
|
let data = JSON.parse(event.target.responseText);
|
||||||
|
|
||||||
if (data.Status == "Success") {
|
if (data.Status == "Success") {
|
||||||
toastr.success("ذخیره سازی با موفقیت انجام شد");
|
toastr.success("ذخیره سازی با موفقیت انجام شد");
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
location.href = `../Panel/User/${data.Result}`;
|
location.href = `../Panel/User/${data.Result}`;
|
||||||
}, 1500);
|
}, 1500);
|
||||||
} else {
|
}
|
||||||
|
else if (data.Status == "DuplicatePhone") {
|
||||||
|
$("#btnSave").attr("onclick", "Save()"); // Re-enable button
|
||||||
|
toastr.error("این شماره تلفن قبلاً در سیستم ثبت شده است!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
$("#btnSave").attr("onclick", "Save()");
|
$("#btnSave").attr("onclick", "Save()");
|
||||||
console.log(data);
|
console.log(data);
|
||||||
toastr.warning("خطا هنگام ذخیره سازی اطلاعات");
|
toastr.warning("خطا هنگام ذخیره سازی اطلاعات");
|
||||||
@ -291,7 +311,7 @@
|
|||||||
confirmButtonText: 'بله'
|
confirmButtonText: 'بله'
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.value) {
|
if (result.value) {
|
||||||
$.post("../api/User/Delete", { Id: Id, UserId: UserId, Token: Token }).done(function (data) {
|
$.post("../api/User/Delete", { Id: Id, UserId: @User.User_Id, Token: "@User.User_Token" }).done(function (data) {
|
||||||
if (data.Status == "Success") {
|
if (data.Status == "Success") {
|
||||||
$(".btns").remove();
|
$(".btns").remove();
|
||||||
toastr.success("حذف با موفقیت انجام شد");
|
toastr.success("حذف با موفقیت انجام شد");
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-dark bg-dark">
|
@*<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-dark bg-dark">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
|
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
|
||||||
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" title="Toggle navigation" aria-controls="navbarSupportedContent"
|
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" title="Toggle navigation" aria-controls="navbarSupportedContent"
|
||||||
@ -22,7 +22,7 @@
|
|||||||
<li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, new { @class = "nav-link" })</li>
|
<li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, new { @class = "nav-link" })</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>*@
|
||||||
</nav>
|
</nav>
|
||||||
<div class="container body-content">
|
<div class="container body-content">
|
||||||
@RenderBody()
|
@RenderBody()
|
||||||
|
|||||||
@ -8,6 +8,17 @@
|
|||||||
</sectionGroup>
|
</sectionGroup>
|
||||||
</configSections>
|
</configSections>
|
||||||
|
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-4.6.1.0" newVersion="4.6.1.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
<!-- ممکن است dependentAssembly های دیگری هم اینجا داشته باشید -->
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
|
|
||||||
|
|
||||||
<system.web.webPages.razor>
|
<system.web.webPages.razor>
|
||||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.9.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.9.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
var User = Session["User"] as User;
|
var User = Session["User"] as User;
|
||||||
if (User == null) { return; }
|
if (User == null) { return; }
|
||||||
bool HasAccess(string Access) => new Functions().HasAccess(User.User_Access, Access);
|
bool HasAccess(string Access) => new Functions().HasAccess(User.User_Access, Access);
|
||||||
|
|
||||||
}
|
}
|
||||||
@section Heads {
|
@section Heads {
|
||||||
@RenderSection("Heads", false)
|
@RenderSection("Heads", false)
|
||||||
@ -81,7 +82,7 @@
|
|||||||
<span></span>
|
<span></span>
|
||||||
</button>
|
</button>
|
||||||
<a href="~/Panel">
|
<a href="~/Panel">
|
||||||
<img class="w-50" src="~/Media/Logo.png" />
|
<img class="w-50" src="~/Media/User.png" />
|
||||||
</a>
|
</a>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<button class="btn p-0 burger-icon ml-4 d-none d-md-block" id="kt_header_mobile_toggle">
|
<button class="btn p-0 burger-icon ml-4 d-none d-md-block" id="kt_header_mobile_toggle">
|
||||||
@ -115,7 +116,7 @@
|
|||||||
<div class="aside aside-left aside-fixed d-flex flex-column flex-row-auto" id="kt_aside">
|
<div class="aside aside-left aside-fixed d-flex flex-column flex-row-auto" id="kt_aside">
|
||||||
<div class="brand flex-column-auto d-flex" id="kt_brand">
|
<div class="brand flex-column-auto d-flex" id="kt_brand">
|
||||||
<a href="~/Panel">
|
<a href="~/Panel">
|
||||||
<img class="w-75" src="~/Media/Logo.png" />
|
<img class="" src="~/Media/User.png" style="width:30%;"/>
|
||||||
</a>
|
</a>
|
||||||
<button class="brand-toggle btn btn-sm px-0 d-none d-md-inline-block" id="kt_aside_toggle">
|
<button class="brand-toggle btn btn-sm px-0 d-none d-md-inline-block" id="kt_aside_toggle">
|
||||||
<span class="svg-icon svg-icon svg-icon-xl">
|
<span class="svg-icon svg-icon svg-icon-xl">
|
||||||
@ -179,6 +180,69 @@
|
|||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@if (HasAccess("ManageNews"))
|
||||||
|
{
|
||||||
|
<li class="menu-item menu-item-submenu" aria-haspopup="true" data-menu-toggle="hover" id="NewsMenu">
|
||||||
|
<a href="javascript:;" class="menu-link menu-toggle">
|
||||||
|
<i class="menu-icon fa fa-newspaper"></i>
|
||||||
|
<span class="menu-text">مدیریت اخبار</span>
|
||||||
|
<i class="menu-arrow"></i>
|
||||||
|
</a>
|
||||||
|
<div class="menu-submenu">
|
||||||
|
<i class="menu-arrow"></i>
|
||||||
|
<ul class="menu-subnav">
|
||||||
|
<li class="menu-item" aria-haspopup="true" id="NewsListMenu">
|
||||||
|
<a href="~/panel/NewsList" class="menu-link">
|
||||||
|
<i class="menu-bullet menu-bullet-line"><span></span></i>
|
||||||
|
<span class="menu-text">لیست اخبار</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@if (HasAccess("ManageItems"))
|
||||||
|
{
|
||||||
|
<li class="menu-item menu-item-submenu" aria-haspopup="true" data-menu-toggle="hover" id="ItemsMenu">
|
||||||
|
<a href="javascript:;" class="menu-link menu-toggle">
|
||||||
|
<i class="menu-icon fa fa-tags"></i>
|
||||||
|
<span class="menu-text">دستهبندی و تگ</span>
|
||||||
|
<i class="menu-arrow"></i>
|
||||||
|
</a>
|
||||||
|
<div class="menu-submenu">
|
||||||
|
<i class="menu-arrow"></i>
|
||||||
|
<ul class="menu-subnav">
|
||||||
|
<li class="menu-item" aria-haspopup="true" id="CategoriesMenu">
|
||||||
|
<a href="~/panel/Items/1" class="menu-link">
|
||||||
|
<i class="menu-bullet menu-bullet-line"><span></span></i>
|
||||||
|
<span class="menu-text">مدیریت دستهبندی</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="menu-item" aria-haspopup="true" id="TagsMenu">
|
||||||
|
<a href="~/panel/Items/2" class="menu-link">
|
||||||
|
<i class="menu-bullet menu-bullet-line"><span></span></i>
|
||||||
|
<span class="menu-text">مدیریت تگها</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@if (HasAccess("SomeAccess"))
|
||||||
|
{
|
||||||
|
<li class="menu-item" aria-haspopup="true" id="ClientsMenu">
|
||||||
|
<a href="~/panel/ClientManagement" class="menu-link">
|
||||||
|
<i class="menu-icon fa fa-users"></i>
|
||||||
|
<span class="menu-text">مدیریت مشتریان</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
|
||||||
@if (HasAccess("ManageSettings"))
|
@if (HasAccess("ManageSettings"))
|
||||||
{
|
{
|
||||||
<li class="menu-item" aria-haspopup="true" id="SettingMenu">
|
<li class="menu-item" aria-haspopup="true" id="SettingMenu">
|
||||||
|
|||||||
16
Web.config
@ -66,6 +66,22 @@
|
|||||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
|
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
|
||||||
<bindingRedirect oldVersion="1.0.0.0-5.2.9.0" newVersion="5.2.9.0" />
|
<bindingRedirect oldVersion="1.0.0.0-5.2.9.0" newVersion="5.2.9.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
||||||
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-4.1.6.0" newVersion="4.1.6.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||||
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
<system.codedom>
|
<system.codedom>
|
||||||
|
|||||||
@ -45,20 +45,72 @@
|
|||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="ClosedXML, Version=0.105.0.0, Culture=neutral, PublicKeyToken=fd1eb21b62ae805b, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\ClosedXML.0.105.0\lib\netstandard2.0\ClosedXML.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="ClosedXML.Parser, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1d5f7376574c51ec, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\ClosedXML.Parser.2.0.0\lib\netstandard2.0\ClosedXML.Parser.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DocumentFormat.OpenXml, Version=3.1.1.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\DocumentFormat.OpenXml.3.1.1\lib\net46\DocumentFormat.OpenXml.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DocumentFormat.OpenXml.Framework, Version=3.1.1.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\DocumentFormat.OpenXml.Framework.3.1.1\lib\net46\DocumentFormat.OpenXml.Framework.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||||
<HintPath>packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
|
<HintPath>packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||||
<HintPath>packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
<HintPath>packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="ExcelNumberFormat, Version=1.1.0.0, Culture=neutral, PublicKeyToken=23c6f5d73be07eca, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\ExcelNumberFormat.1.1.0\lib\net20\ExcelNumberFormat.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Bcl.HashCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="RestSharp">
|
<Reference Include="RBush, Version=4.0.0.0, Culture=neutral, PublicKeyToken=c77e27b81f4d0187, processorArchitecture=MSIL">
|
||||||
<HintPath>..\..\..\..\..\repo\AloCmsShopNew\bin\RestSharp.dll</HintPath>
|
<HintPath>packages\RBush.Signed.4.0.0\lib\net47\RBush.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="RestSharp, Version=112.1.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\RestSharp.112.1.0\lib\net48\RestSharp.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="SixLabors.Fonts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\SixLabors.Fonts.1.0.0\lib\netstandard2.0\SixLabors.Fonts.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Numerics" />
|
||||||
|
<Reference Include="System.Numerics.Vectors, Version=4.1.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Security" />
|
<Reference Include="System.Security" />
|
||||||
|
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Text.Json, Version=8.0.0.4, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Text.Json.8.0.4\lib\net462\System.Text.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Web.Entity" />
|
<Reference Include="System.Web.Entity" />
|
||||||
<Reference Include="System.Web.ApplicationServices" />
|
<Reference Include="System.Web.ApplicationServices" />
|
||||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||||
@ -126,6 +178,7 @@
|
|||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
<HintPath>packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
|
<HintPath>packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform">
|
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform">
|
||||||
@ -172,7 +225,14 @@
|
|||||||
<Compile Include="Global.asax.cs">
|
<Compile Include="Global.asax.cs">
|
||||||
<DependentUpon>Global.asax</DependentUpon>
|
<DependentUpon>Global.asax</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Models\Client.cs">
|
||||||
|
<DependentUpon>Model1.tt</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Models\NewsModel.cs" />
|
||||||
<Compile Include="Models\Functions.cs" />
|
<Compile Include="Models\Functions.cs" />
|
||||||
|
<Compile Include="Models\Item.cs">
|
||||||
|
<DependentUpon>Model1.tt</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Models\Model1.Context.cs">
|
<Compile Include="Models\Model1.Context.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
@ -188,6 +248,9 @@
|
|||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Model1.edmx</DependentUpon>
|
<DependentUpon>Model1.edmx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Models\News.cs">
|
||||||
|
<DependentUpon>Model1.tt</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Models\Setting.cs">
|
<Compile Include="Models\Setting.cs">
|
||||||
<DependentUpon>Model1.tt</DependentUpon>
|
<DependentUpon>Model1.tt</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -3497,6 +3560,11 @@
|
|||||||
<Content Include="Views\Panel\Users.cshtml" />
|
<Content Include="Views\Panel\Users.cshtml" />
|
||||||
<Content Include="Views\Panel\User.cshtml" />
|
<Content Include="Views\Panel\User.cshtml" />
|
||||||
<Content Include="Views\Panel\Login.cshtml" />
|
<Content Include="Views\Panel\Login.cshtml" />
|
||||||
|
<Content Include="Views\Home\AllNews.cshtml" />
|
||||||
|
<Content Include="Views\Panel\NewsList.cshtml" />
|
||||||
|
<Content Include="Views\Panel\AddNews.cshtml" />
|
||||||
|
<Content Include="Views\Panel\Items.cshtml" />
|
||||||
|
<Content Include="Views\Panel\ClientManagement.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="App_Data\" />
|
<Folder Include="App_Data\" />
|
||||||
|
|||||||
@ -2,7 +2,12 @@
|
|||||||
<packages>
|
<packages>
|
||||||
<package id="Antlr" version="3.5.0.2" targetFramework="net48" />
|
<package id="Antlr" version="3.5.0.2" targetFramework="net48" />
|
||||||
<package id="bootstrap" version="5.2.3" targetFramework="net48" />
|
<package id="bootstrap" version="5.2.3" targetFramework="net48" />
|
||||||
|
<package id="ClosedXML" version="0.105.0" targetFramework="net48" />
|
||||||
|
<package id="ClosedXML.Parser" version="2.0.0" targetFramework="net48" />
|
||||||
|
<package id="DocumentFormat.OpenXml" version="3.1.1" targetFramework="net48" />
|
||||||
|
<package id="DocumentFormat.OpenXml.Framework" version="3.1.1" targetFramework="net48" />
|
||||||
<package id="EntityFramework" version="6.2.0" targetFramework="net48" />
|
<package id="EntityFramework" version="6.2.0" targetFramework="net48" />
|
||||||
|
<package id="ExcelNumberFormat" version="1.1.0" targetFramework="net48" />
|
||||||
<package id="jQuery" version="3.7.0" targetFramework="net48" />
|
<package id="jQuery" version="3.7.0" targetFramework="net48" />
|
||||||
<package id="Microsoft.AspNet.Mvc" version="5.2.9" targetFramework="net48" />
|
<package id="Microsoft.AspNet.Mvc" version="5.2.9" targetFramework="net48" />
|
||||||
<package id="Microsoft.AspNet.Razor" version="3.2.9" targetFramework="net48" />
|
<package id="Microsoft.AspNet.Razor" version="3.2.9" targetFramework="net48" />
|
||||||
@ -13,9 +18,23 @@
|
|||||||
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.9" targetFramework="net48" />
|
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.9" targetFramework="net48" />
|
||||||
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.9" targetFramework="net48" />
|
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.9" targetFramework="net48" />
|
||||||
<package id="Microsoft.AspNet.WebPages" version="3.2.9" targetFramework="net48" />
|
<package id="Microsoft.AspNet.WebPages" version="3.2.9" targetFramework="net48" />
|
||||||
|
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
|
||||||
|
<package id="Microsoft.Bcl.HashCode" version="1.1.1" targetFramework="net48" />
|
||||||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net48" />
|
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net48" />
|
||||||
|
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net48" />
|
||||||
<package id="Microsoft.Web.Infrastructure" version="2.0.0" targetFramework="net48" />
|
<package id="Microsoft.Web.Infrastructure" version="2.0.0" targetFramework="net48" />
|
||||||
<package id="Modernizr" version="2.8.3" targetFramework="net48" />
|
<package id="Modernizr" version="2.8.3" targetFramework="net48" />
|
||||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
|
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
|
||||||
|
<package id="RBush.Signed" version="4.0.0" targetFramework="net48" />
|
||||||
|
<package id="RestSharp" version="112.1.0" targetFramework="net48" />
|
||||||
|
<package id="SixLabors.Fonts" version="1.0.0" targetFramework="net48" />
|
||||||
|
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
||||||
|
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
|
||||||
|
<package id="System.Numerics.Vectors" version="4.6.1" targetFramework="net48" />
|
||||||
|
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
|
||||||
|
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net48" />
|
||||||
|
<package id="System.Text.Json" version="8.0.4" targetFramework="net48" />
|
||||||
|
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
|
||||||
|
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
|
||||||
<package id="WebGrease" version="1.6.0" targetFramework="net48" />
|
<package id="WebGrease" version="1.6.0" targetFramework="net48" />
|
||||||
</packages>
|
</packages>
|
||||||