Sử dụng kết quả bài Lab05 cho MyEstore project để tiếp tục.
Tạo mới Controller tên HangHoa và khai báo nhúng CSDL vào để làm việc
public class HangHoaController : Controller
{
private readonly MyeStoreContext _ctx;
public HangHoaController(MyeStoreContext ctx)
{
_ctx = ctx;
}
public IActionResult Index()
{
return View();
}
}
Thiết kế View cho action Index:
<h1>Tìm kiếm</h1>
<form asp-action="Index">
Tìm theo tên: <input name="Keyword" /><br />
Giá từ: <input type="number" name="FromPrice" />
đến: <input type="number" name="ToPrice" />
<button>Tìm kiếm</button>
</form>
Định nghĩa view model để truyền và hiển thị đúng dữ liệu cần:
public class HangHoaVM
{
public int MaHh { get; set; }
public string TenHh { get; set; } = null!;
public string Hinh { get; set; } = null!;
public double DonGia { get; set; }
public string TenLoai { get; set; }
}
Tạo mới action View dạng POST để nhận và xử lý dữ liệu:
[HttpPost]
public IActionResult Index(string? Keyword, double? FromPrice, double? ToPrice)
{
var result = _ctx.HangHoas.AsQueryable();
if (!string.IsNullOrEmpty(Keyword))
{
result = result.Where(hh => hh.TenHh.Contains(Keyword));
}
if (FromPrice.HasValue)
{
result = result.Where(hh => hh.DonGia >= FromPrice);
}
if (ToPrice.HasValue)
{
result = result.Where(hh => hh.DonGia <= ToPrice);
}
var data = result.Select(hh => new HangHoaVM
{
MaHh = hh.MaHh, TenHh = hh.TenHh,
DonGia = hh.DonGia ?? 0,
Hinh = hh.Hinh,
TenLoai = hh.MaLoaiNavigation.TenLoai
}).ToList();
return View(data);
}
Trở lại view Index để hiển thị kết quả tìm kiếm.
Khai báo ở đầu view
@model List<HangHoaVM>
Chèn thêm code ở phía bên dưới
@if (Model != null)
{
<h2>Kết quả tìm kiếm</h2>
<table>
@foreach (var hh in Model)
{
<tr>
<td>@hh.MaHh</td>
<td>@hh.TenHh</td>
<td>@hh.DonGia.ToString("#,##0.0") $</td>
<td>@hh.TenLoai</td>
<td>
<img src="~/Hinh/HangHoa/@hh.Hinh"
alt="@hh.TenHh" />
</td>
</tr>
}
</table>
}
public class ThongKeController : Controller
{
private readonly MyeStoreContext _ctx;
public ThongKeController(MyeStoreContext ctx)
{
_ctx = ctx;
}
}
public IActionResult ThongKeTheoLoai()
{
var data = _ctx.ChiTietHds
.GroupBy(cthd => new
{
MaLoai = cthd.MaHhNavigation.MaLoai,
TenLoai = cthd.MaHhNavigation.MaLoaiNavigation.TenLoai,
}).Select(p => new {
p.Key.MaLoai, p.Key.TenLoai,
DoanhThu = p.Sum(cthd => cthd.SoLuong * cthd.DonGia)
});
return Json(data);
}
GroupBy xong thì lấy key theo thuộc tính key.
VD:
+ Group theo 1 field:
.....GroupBy(x => x.ABC)
.Select(x => new {ABC=x.Key})...
+ Group theo nhiều field (như vú dụ trên)
.....GroupBy(x => new {x.ABC, x.DEF})
.Select(x => new {ABC=x.Key.ABC, DEF=x.Key.DEF})...
Nếu người dùng không nhập thì mặt định 30 ngày từ ngày hiện tại.
const int KHOANG_CACH_NGAY = 30;
public IActionResult ThongKeTheoLoai(DateTime? TuNgay, DateTime? DenNgay)
{
if (!TuNgay.HasValue && !DenNgay.HasValue)
{
DenNgay = DateTime.Now;
TuNgay = DenNgay.Value.AddDays(-KHOANG_CACH_NGAY);
}
else if (TuNgay.HasValue && !DenNgay.HasValue)
{
DenNgay = TuNgay.Value.AddDays(KHOANG_CACH_NGAY);
}
else if (!TuNgay.HasValue && DenNgay.HasValue)
{
TuNgay = DenNgay.Value.AddDays(-KHOANG_CACH_NGAY);
}
var data = _ctx.ChiTietHds
.Where(p => p.MaHdNavigation.NgayDat >= TuNgay && p.MaHdNavigation.NgayDat <= DenNgay)
.GroupBy(cthd => new
{
MaLoai = cthd.MaHhNavigation.MaLoai,
TenLoai = cthd.MaHhNavigation.MaLoaiNavigation.TenLoai,
}).Select(p => new
{
p.Key.MaLoai,
p.Key.TenLoai,
DoanhThu = p.Sum(cthd => cthd.SoLuong * cthd.DonGia)
});
return Json(data);
}
Copy nội dung source code mẫu của ChartJS ở trang https://www.chartjs.org/docs/latest/getting-started/ vô View Index, chạy thử và quan sát
<h2>THỐNG KÊ</h2>
<fieldset>
Từ ngày: <input id="tuNgay" type="date" />
đến ngày: <input id="denNgay" type="date" />
<button type="button" id="btnTraCuu">Tra cứu</button>
</fieldset>
thêm phần xử lý AJAX:
@section Scripts{
<script>
$(document).ready(function () {
$("#btnTraCuu").click(function () {
$.ajax({
url: "/ThongKe/ThongKeTheoLoai",
data: {
TuNgay: $("#tuNgay").val(),
DenNgay: $("#denNgay").val(),
},
success: function (data) {
console.log(data);
}
});
});
});
</script>
}
xử lý kết quả trả về (chưa hoàn chỉnh):
@section Scripts{
<script>
$(document).ready(function () {
$("#btnTraCuu").click(function () {
$.ajax({
url: "/ThongKe/ThongKeTheoLoai",
data: {
TuNgay: $("#tuNgay").val(),
DenNgay: $("#denNgay").val(),
},
success: function (data) {
let myLabels = data.map((item) => item.tenLoai);
let myStatitics = data.map((item) => item.doanhThu);
new Chart(ctx, {
type: 'bar',
data: {
labels: myLabels,
datasets: [{
label: '$',
data: myStatitics,
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
}
});
});
});
</script>
}