ورود

View Full Version : سوال: نحوه ساخت سفارش کالا به شکل ضمیمه شده



jaykob
پنج شنبه 03 دی 1394, 10:21 صبح
سلام


من می خوام یک فرم به شکل زیر برای ثبت کالا بسازم که کاربر کد کالا و تعداد رو زد بره دیتابیس مشخصات رو در لیست بیاره و مثلا ۵ تا کالا ( این کالا ها توی session یا این مدل چیزی ذخیره بشه ) و وقتی کاربر روی ثبت فاکتور کلیک کرده لیست کالا ها بره توی دیتابیس ذخیره بشه . واقعا نمی دونم باید این که کاربر روی دکمه اضافه کن کلیک کرده چطور کالا رو ببرم توی session و توی لیست نشون بدم و در عین حال سرعت خیلی خیلی مهم هست و می خوام تمامی کارها با javascript و ... باشه که کاربر درخواستی سمت سرور نفرسته و بر نگرده ...

لطفا یک راهنمایی جامع بکنید

تشکر

مهدی کرامتی
پنج شنبه 03 دی 1394, 12:40 عصر
تو یک پروژه من چنین کاری کردم.

این View نمایش فهرست کالاهاست که با یک دکمه که زیر هر کالاست شماره کالا به یک Web Api ارسال میشه که تو سشن نگهداری شود:


@model List<eShopMvc.Models.Products>

<style type="text/css">
.ProductItem {
text-align: center;
padding-bottom: 10px;
min-height: 150px;
}
</style>

<div class="row">
@foreach (var item in Model)
{
<div class="col-md-3 ProductItem">
<div class="row">
<div class="col-md-12">
@item.ProductTitle
</div>
<div class="col-md-12">
<img src="@item.ProductThumbnailImageUrl" class="img-thumbnail"/>
</div>
<div class="col-md-12">
قیمت: @item.ProductPrice.ToString("#,0 ریال")
</div>
<div class="col-md-12">
<input type="button" class="btn btn-default" value="افزودن به سبد خرید" id="btnAddToBasket_@item.ProductID">
</div>
</div>
</div>
}
</div>

<script type="text/javascript">
$(document).ready(function () {
$("[id*=btnAddToBasket]").each(function () {
$(this).click(function () {
var productid = $(this).attr("id").match(/[\d]+$/);
$.ajax({
url: "/api/ShoppingCartApi",
data: { ProductID: productid },
type: "GET"
}).done(function (result) {
if (result) {
$("#cartinfo").fadeOut(200).html("تعداد اقلام موجود در سبد خرید: " + result).fadeIn(200);
} else {
}
});

});
});
});
</script>


این هم سورس اون کلاس Web Api که درخواست های Ajax رو تحویل می گیره:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using eShopMvc.Models;
using eShopMVC;

namespace eShopMVC.Controllers
{
public class ShoppingCartApiController : ApiController
{
//eShopMVCEntities db = new eShopMVCEntities();
public int Get()
{
int cartitemscount = 0;
var Session = HttpContext.Current.Session;
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> products = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

foreach (var productInShoppingCart in products)
{
cartitemscount += productInShoppingCart.ProductCount;
}
}
return cartitemscount;
}

public int Get(int ProductID)
{
int cartitemscount = 0;

var Session = HttpContext.Current.Session;

List<ProductInShoppingCart> products = new List<ProductInShoppingCart>();

if (Session["ShoppingCartItems"] != null)
{
products = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

ProductInShoppingCart selected = products.Find(p => p.ProductID == ProductID);
if (selected != null)
{
selected.ProductCount++;
int index = products.FindIndex(p => p.ProductID == ProductID);
products[index] = selected;
}
else
{
selected = new ProductInShoppingCart() { ProductID = ProductID, ProductCount = 1 };
products.Add(selected);
}
Session["ShoppingCartItems"] = products;

}
else
{
ProductInShoppingCart selected = new ProductInShoppingCart() {ProductID = ProductID,ProductCount = 1};
products.Add(selected);
Session["ShoppingCartItems"] = products;
}
foreach (var productInShoppingCart in products)
{
cartitemscount += productInShoppingCart.ProductCount;
}
return cartitemscount;
}
}
}


در یک جای دیگه پروژه، در یک صفحه لیست کالاها که در قالب یک لیست در سشن نگهداری شده خوانده میشه و در یک گرید نمایش داده میشه. امکان افزودن تعداد و کاهش تعداد کالاهای انتخاب شده و نیز حذف اون ها از لیست در این گرید تعبیه شده.
سورس کنترلر مذکور:
public class ShoppingCartController : Controller
{
eShopMVCEntities db = new eShopMVCEntities();
//
// GET: /ShoppingCart/



public ActionResult Index()
{
List<ShoppingCartViewModel> cartcontents = new List<ShoppingCartViewModel>();
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> productsInCart = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

var dbProducts = db.Products.ToList();

cartcontents = (from pr in dbProducts
join pic in productsInCart
on pr.ProductID equals pic.ProductID
select new ShoppingCartViewModel
{
ProductID = pr.ProductID,
ProductTitle = pr.ProductTitle,
ProductPrice = pr.ProductPrice,
ProductCount = pic.ProductCount,
RowTotal = pr.ProductPrice * pic.ProductCount
}).ToList();
return View(cartcontents);
}
return View(cartcontents);
}

public ActionResult SubCount(int id)
{
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> productsInCart = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

int index = productsInCart.FindIndex(p => p.ProductID == id);

ProductInShoppingCart item = productsInCart[index];
if (item.ProductCount == 1)
{
productsInCart.RemoveAt(index);
}
else
{
item.ProductCount--;
productsInCart[index] = item;
}
Session["ShoppingCartItems"] = productsInCart;
}
return RedirectToAction("Index");
}

public ActionResult AddCount(int id)
{
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> productsInCart = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

int index = productsInCart.FindIndex(p => p.ProductID == id);

ProductInShoppingCart item = productsInCart[index];
item.ProductCount++;
productsInCart[index] = item;
Session["ShoppingCartItems"] = productsInCart;
}
return RedirectToAction("Index");
}

public ActionResult Delete(int id)
{
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> productsInCart = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;
int index = productsInCart.FindIndex(p => p.ProductID == id);
productsInCart.RemoveAt(index);
Session["ShoppingCartItems"] = productsInCart;
}
return RedirectToAction("Index");
}
}

و این هم ویو مربوط به کنترلر فوق:

@model IEnumerable<eShopMvc.Models.ShoppingCartViewModel>

@{
ViewBag.Title = "Index";
}

<h2>فهرست</h2>

<div class="k-rtl">
@(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(model => model.ProductID).Visible(false);
columns.Bound(model => model.ProductTitle).Width(120);
columns.Bound(model => model.ProductPrice).Width(80);
// .FooterTemplate(@<text>جمع: @string.Format("{0:#,0 ریال}",item.Sum != null ? item.Sum.Value : 0)</text>);
columns.Bound(model => model.ProductCount).Width(50)
.FooterTemplate(@<text>جمع: @string.Format("{0:#,0 عدد}",item.Sum != null ? item.Sum.Value : 0)</text>);
columns.Bound(model => model.RowTotal).Width(50)
.FooterTemplate(@<text>جمع: @string.Format("{0:#,0 ریال}",item.Sum != null ? item.Sum.Value : 0)</text>);
columns.Bound(item => @item.ProductID).Title("دستورات").Filterable(false).Groupable(false)
.Template(@<text>
@Html.ActionLink("کاهش تعداد", "SubCount", new { id = @item.ProductID }, new { @class = "k-button k-button-icontext" })
@Html.ActionLink("افزایش تعداد", "AddCount", new { id = @item.ProductID }, new { @class = "k-button k-button-icontext" })
@Html.ActionLink("حذف", "Delete", new { id = @item.ProductID }, new { @class = "k-button k-button-icontext" })
</text>).Width(200);

})
.ToolBar(toolbar =>
{
toolbar.Custom().Action("Finalize", "ShoppingCart").Text("تکمیل خرید و تسویه حساب");
}
)
.Groupable()
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.DataSource(dataSource => dataSource
.Server()
.Aggregates(aggregates =>
{
aggregates.Add(p => p.ProductPrice).Sum();
aggregates.Add(p => p.ProductCount).Sum();
aggregates.Add(p => p.RowTotal).Sum();
})
.Model(model => model.Id(item => item.ProductID))
)
)
</div>

sohil_ww
پنج شنبه 03 دی 1394, 15:22 عصر
تو یک پروژه من چنین کاری کردم.

این View نمایش فهرست کالاهاست که با یک دکمه که زیر هر کالاست شماره کالا به یک Web Api ارسال میشه که تو سشن نگهداری شود:


@model List<eShopMvc.Models.Products>

<style type="text/css">
.ProductItem {
text-align: center;
padding-bottom: 10px;
min-height: 150px;
}
</style>

<div class="row">
@foreach (var item in Model)
{
<div class="col-md-3 ProductItem">
<div class="row">
<div class="col-md-12">
@item.ProductTitle
</div>
<div class="col-md-12">
<img src="@item.ProductThumbnailImageUrl" class="img-thumbnail"/>
</div>
<div class="col-md-12">
قیمت: @item.ProductPrice.ToString("#,0 ریال")
</div>
<div class="col-md-12">
<input type="button" class="btn btn-default" value="افزودن به سبد خرید" id="btnAddToBasket_@item.ProductID">
</div>
</div>
</div>
}
</div>

<script type="text/javascript">
$(document).ready(function () {
$("[id*=btnAddToBasket]").each(function () {
$(this).click(function () {
var productid = $(this).attr("id").match(/[\d]+$/);
$.ajax({
url: "/api/ShoppingCartApi",
data: { ProductID: productid },
type: "GET"
}).done(function (result) {
if (result) {
$("#cartinfo").fadeOut(200).html("تعداد اقلام موجود در سبد خرید: " + result).fadeIn(200);
} else {
}
});

});
});
});
</script>


این هم سورس اون کلاس Web Api که درخواست های Ajax رو تحویل می گیره:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using eShopMvc.Models;
using eShopMVC;

namespace eShopMVC.Controllers
{
public class ShoppingCartApiController : ApiController
{
//eShopMVCEntities db = new eShopMVCEntities();
public int Get()
{
int cartitemscount = 0;
var Session = HttpContext.Current.Session;
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> products = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

foreach (var productInShoppingCart in products)
{
cartitemscount += productInShoppingCart.ProductCount;
}
}
return cartitemscount;
}

public int Get(int ProductID)
{
int cartitemscount = 0;

var Session = HttpContext.Current.Session;

List<ProductInShoppingCart> products = new List<ProductInShoppingCart>();

if (Session["ShoppingCartItems"] != null)
{
products = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

ProductInShoppingCart selected = products.Find(p => p.ProductID == ProductID);
if (selected != null)
{
selected.ProductCount++;
int index = products.FindIndex(p => p.ProductID == ProductID);
products[index] = selected;
}
else
{
selected = new ProductInShoppingCart() { ProductID = ProductID, ProductCount = 1 };
products.Add(selected);
}
Session["ShoppingCartItems"] = products;

}
else
{
ProductInShoppingCart selected = new ProductInShoppingCart() {ProductID = ProductID,ProductCount = 1};
products.Add(selected);
Session["ShoppingCartItems"] = products;
}
foreach (var productInShoppingCart in products)
{
cartitemscount += productInShoppingCart.ProductCount;
}
return cartitemscount;
}
}
}


در یک جای دیگه پروژه، در یک صفحه لیست کالاها که در قالب یک لیست در سشن نگهداری شده خوانده میشه و در یک گرید نمایش داده میشه. امکان افزودن تعداد و کاهش تعداد کالاهای انتخاب شده و نیز حذف اون ها از لیست در این گرید تعبیه شده.
سورس کنترلر مذکور:
public class ShoppingCartController : Controller
{
eShopMVCEntities db = new eShopMVCEntities();
//
// GET: /ShoppingCart/



public ActionResult Index()
{
List<ShoppingCartViewModel> cartcontents = new List<ShoppingCartViewModel>();
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> productsInCart = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

var dbProducts = db.Products.ToList();

cartcontents = (from pr in dbProducts
join pic in productsInCart
on pr.ProductID equals pic.ProductID
select new ShoppingCartViewModel
{
ProductID = pr.ProductID,
ProductTitle = pr.ProductTitle,
ProductPrice = pr.ProductPrice,
ProductCount = pic.ProductCount,
RowTotal = pr.ProductPrice * pic.ProductCount
}).ToList();
return View(cartcontents);
}
return View(cartcontents);
}

public ActionResult SubCount(int id)
{
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> productsInCart = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

int index = productsInCart.FindIndex(p => p.ProductID == id);

ProductInShoppingCart item = productsInCart[index];
if (item.ProductCount == 1)
{
productsInCart.RemoveAt(index);
}
else
{
item.ProductCount--;
productsInCart[index] = item;
}
Session["ShoppingCartItems"] = productsInCart;
}
return RedirectToAction("Index");
}

public ActionResult AddCount(int id)
{
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> productsInCart = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;

int index = productsInCart.FindIndex(p => p.ProductID == id);

ProductInShoppingCart item = productsInCart[index];
item.ProductCount++;
productsInCart[index] = item;
Session["ShoppingCartItems"] = productsInCart;
}
return RedirectToAction("Index");
}

public ActionResult Delete(int id)
{
if (Session["ShoppingCartItems"] != null)
{
List<ProductInShoppingCart> productsInCart = Session["ShoppingCartItems"] as List<ProductInShoppingCart>;
int index = productsInCart.FindIndex(p => p.ProductID == id);
productsInCart.RemoveAt(index);
Session["ShoppingCartItems"] = productsInCart;
}
return RedirectToAction("Index");
}
}

و این هم ویو مربوط به کنترلر فوق:

@model IEnumerable<eShopMvc.Models.ShoppingCartViewModel>

@{
ViewBag.Title = "Index";
}

<h2>فهرست</h2>

<div class="k-rtl">
@(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(model => model.ProductID).Visible(false);
columns.Bound(model => model.ProductTitle).Width(120);
columns.Bound(model => model.ProductPrice).Width(80);
// .FooterTemplate(@<text>جمع: @string.Format("{0:#,0 ریال}",item.Sum != null ? item.Sum.Value : 0)</text>);
columns.Bound(model => model.ProductCount).Width(50)
.FooterTemplate(@<text>جمع: @string.Format("{0:#,0 عدد}",item.Sum != null ? item.Sum.Value : 0)</text>);
columns.Bound(model => model.RowTotal).Width(50)
.FooterTemplate(@<text>جمع: @string.Format("{0:#,0 ریال}",item.Sum != null ? item.Sum.Value : 0)</text>);
columns.Bound(item => @item.ProductID).Title("دستورات").Filterable(false).Groupable(false)
.Template(@<text>
@Html.ActionLink("کاهش تعداد", "SubCount", new { id = @item.ProductID }, new { @class = "k-button k-button-icontext" })
@Html.ActionLink("افزایش تعداد", "AddCount", new { id = @item.ProductID }, new { @class = "k-button k-button-icontext" })
@Html.ActionLink("حذف", "Delete", new { id = @item.ProductID }, new { @class = "k-button k-button-icontext" })
</text>).Width(200);

})
.ToolBar(toolbar =>
{
toolbar.Custom().Action("Finalize", "ShoppingCart").Text("تکمیل خرید و تسویه حساب");
}
)
.Groupable()
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.DataSource(dataSource => dataSource
.Server()
.Aggregates(aggregates =>
{
aggregates.Add(p => p.ProductPrice).Sum();
aggregates.Add(p => p.ProductCount).Sum();
aggregates.Add(p => p.RowTotal).Sum();
})
.Model(model => model.Id(item => item.ProductID))
)
)
</div>



طور کل استفاده از Session State ها و نگه داشتن State کاربر در حافظه سمت سرور، کار جالبی نیست و توصیه نمیشه. برای اهمیت موضوع میشه به این نکته اکتفا کرد که یکی از اصول طراحی سرویس های REST همین موضوع Stateless بودن می باشد (اطلاعات بیشتر در ویکیپدیا (https://en.wikipedia.org/wiki/Representational_state_transfer#Stateless)) .