Đồ án Thiết kế và lập trình Website

pdf 168 trang thiennha21 14/04/2022 9112
Bạn đang xem 20 trang mẫu của tài liệu "Đồ án Thiết kế và lập trình Website", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfdo_an_thiet_ke_va_lap_trinh_website.pdf

Nội dung text: Đồ án Thiết kế và lập trình Website

  1. BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÀ RỊA - VŨNG TÀU KHOA CÔNG NGHỆ KỸ THUẬT - NÔNG NGHIỆP CÔNG NGHỆ CAO  ĐỒ ÁN TỐT NGHIỆP ĐỀ TÀI THIẾT KẾ VÀ LẬP TRÌNH WEBSITE Giảng viên hướng dẫn : ThS. Nguyễn Lan Hương Sinh viên thực hiện : Phan Tiến Đạt Trình độ đào tạo : Đại Học Chính Quy Ngành đào tạo : Công Nghệ Thông Tin Chuyên Ngành : Máy Tính MSSV : 16031147 Lớp : DH16MT Niên khóa : 2016 - 2020 VŨNG TÀU, NĂM 2020
  2. ĐẠI HỌC BÀ RỊA – VŨNG TÀU CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM KHOA KỸ THUẬT CN-NNCN CAO Độc lập – Tự do – Hạnh phúc ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ ⎯ PHIẾU GIAO ĐỀ TÀI ĐỒ ÁN/ KHÓA LUẬN TỐT NGHIỆP Họ tên sinh viên: Phan Tiến Đạt Mã SV: 16031147 Lớp: DH16MT Ngành: Công Nghệ Thông Tin Khóa: 16 Tên đề tài: Thiết kế và lập trình Website Mục tiêu đề tài: Thiết kế và lập trình website giới thiệu, quảng bá về công ty (công ty lấy tên Viko), đưa tới mọi người hình ảnh về công ty cùng những thông tin sản phẩm, dự án của công ty đó. Đồng thời bên phía công ty cũng được cung cấp những chức năng để quản trị website một cách tốt nhất. Kết quả dự kiến: Sản phẩm website có giao diện đẹp mắt, bố cục đơn giản, tích hợp nhiều chức năng để người dùng dễ dàng tra cứu, tìm hiểu các thông tin về công ty. Qua đó hình ảnh công ty sẽ được quảng bá một cách tốt nhất đến mọi người. Thời gian thực hiện: Bắt đầu từ 02/03/2020 đến 10/05/2020. Vũng Tàu, ngày tháng năm TRƯỞNG KHOA CNTT GIẢNG VIÊN HƯỚNG DẪN (Ký và ghi rõ họ tên) (Ký và ghi rõ họ tên)
  3. NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN Ngày Tháng Năm Giáo Viên Hướng Dẫn (Ký, ghi rõ họ và tên)
  4. NHẬN XÉT CỦA GIÁO VIÊN PHẢN BIỆN Ngày Tháng Năm Giáo Viên Phản Biện (Ký, ghi rõ họ và tên)
  5. LỜI CAM ĐOAN Đồ án này là công trình nghiên cứu và xây dựng của cá nhân tôi, được thực hiện dưới sự hướng dẫn khoa học của Ths. Nguyễn Lan Hương. Các số liệu, những kết luận nghiên cứu được trình bày trong đồ án này là do tôi tự tìm hiểu và hoàn toàn trung thực. Tôi xin hoàn toàn chịu trách nhiệm về lời cam đoan này. Vũng Tàu, tháng 4 năm 2020 Sinh Viên Thực Hiện Phan Tiến Đạt
  6. LỜI CẢM ƠN Tôi xin chân thành cảm ơn khoa Công nghệ thông tin, trường Đại học Bà Rịa – Vũng Tàu đã tạo điều kiện thuận lợi cho tôi thực hiện đề tài này. Tôi cũng xin được gửi lời cảm ơn chân thành nhất đến Ths. Nguyễn Lan Hương, người đã tận tình chỉ bảo, định hướng đi và hướng dẫn tôi thực hiện đề tài này. Bên cạnh đó, tôi xin gửi lời cảm ơn đến các thầy cô, những người đã giảng dạy, tạo điều kiện cho tôi tích lũy được những kiến thức quý báu trong những năm học qua. Dù đã cố gắng hoàn thành đề tài Website giới thiệu công ty Viko, nhưng do thời gian hạn hẹp và khả năng còn hạn chế nên chắc chắn sẽ có những thiếu sót không tránh khỏi. Tôi mong nhận được sự thông cảm và tận tình chỉ bảo của các thầy cô và góp ý từ các bạn. Vũng Tàu, tháng 4 năm 2020 Sinh viên thực hiện Phan Tiến Đạt
  7. MỤC LỤC DANH MỤC CÁC BẢNG 1 DANH MỤC CÁC HÌNH ẢNH 2 LỜI MỞ ĐẦU 5 CHƯƠNG 1: CƠ SỞ LÝ THUYẾT VÀ KHẢO SÁT 7 1.1 HTML,CSS và JavaScript 7 1.1.1 HTML là gì? 7 1.1.2 CSS là gì? 7 1.1.3 JavaScript là gì? 8 1.2 Bootstrap 8 1.2.1 Bootstrap là gì? 8 1.2.2 Tại sao nên dùng Bootstrap? 9 1.3 JQuery 9 1.3.1 JQuery là gì? 9 1.3.2 Tại sao nên dùng jQuery? 9 1.4 Ajax 10 1.4 Ajax là gì? 10 1.4.2 Tại sao nên dùng Ajax? 11 1.5 Lararel 11 1.5.1 Laravel là gì? 11 1.5.2 Tại sao nên dùng Laravel? 13 1.6 PHP 15 1.6.1 PHP là gì? 15 1.6.2 Tại sao nên dùng PHP 16 1.7 Khảo Sát Hiện Trạng 17 1.7.1 Khảo sát thực tế 17 1.7.2 Khảo sát các website tương tự 18
  8. CHƯƠNG 2: TỔNG QUAN CHỨC NĂNG WEBSITE 24 2.1 Quan Điểm Của Sản Phẩm 24 2.2 Chức Năng Sản Phẩm 24 2.3 Người Dùng 24 2.4 Các Ràng Buộc 25 CHƯƠNG 3: YÊU CẦU CHỨC NĂNG WEBSITE 26 3.1 Xem tin 26 3.2 Tìm kiếm sản phẩm 26 3.3 Lọc sản phẩm 26 3.4 Gửi yêu cầu nhận báo giá 26 3.5 Nhận xét bài viết về sản phẩm 26 3.6 Đăng nhập/đăng xuất 26 3.7 Quản lý các tin đăng trên website 27 3.8 Nhận các thông báo yêu cầu từ khách hàng 27 3.9 Quản lý thông tin tài khoản 27 CHƯƠNG 4: MÔ HÌNH USECASE 28 4.1 Tác nhân 28 4.2 Các yêu cầu chức năng 28 4.3 Lược Đồ Use Case 30 4.4 Chi Tiết Các Use Case 31 CHƯƠNG 5: THIẾT KẾ WEBSITE 59 5.1 Thiết kế cơ sở dữ liệu 59 5.1.1 Lược đồ cơ sở dữ liệu 59 5.1.2 Chi tiết các trường 59 5.2 Mối quan hệ giữa các bản dữ liệu 64 5.3 Thiết kế giao diện Website – Front-End 64 5.4 Lập trình Website – Back-End với Laravel 85 5.5 Một số đoạn code nổi bật 145 KẾT LUẬN 156 TÀI LIỆU THAM KHẢO 159
  9. DANH MỤC CÁC BẢNG TT Số hiệu Nội dung Trang Bảng các tác nhân và quyền của 1 Bảng 4.1 28 tác nhân trong UseCase Bảng các yêu cầu chức năng hệ 2 Bảng 4.2 28 thống 3 Bảng 4.3 Bảng chi tiết các UseCase 31 - 58 4 Bảng 5.1 Bảng Table tai_khoans 59 - 60 5 Bảng 5.2 Bảng Table infoct 60 6 Bảng 5.3 Bảng Table thanhpham 60 - 61 7 Bảng 5.4 Bảng Table baogia 61 8 Bảng 5.5 Bảng Table sanpham 61 9 Bảng 5.6 Bảng Table loaisanpham 62 10 Bảng 5.7 Bảng Table loaisanpham_sanpham 62 11 Bảng 5.8 Bảng Table hinhsanpham 62 12 Bảng 5.9 Bảng Table nhanxet 62 - 63 1
  10. DANH MỤC CÁC HÌNH ẢNH TT Số hiệu Nội dung Trang Các phiên bản của laravel đến tháng 1 Hình 1.1 12 4 năm 2020 Cách thức hoạt động MVC trong 2 Hình 1.2 14 Laravel Những ngôn ngữ lập trình phổ biến 3 Hình 1.3 16 từ năm 1965 – 2019 4 Hình 1.4 So sánh giữa ASP và PHP 17 5 Hình 1.5 Slide hình ảnh sản phẩm 19 Mẫu gửi thông tin yêu cầu tới công 6 Hình 1.6 20 ty 7 Hình 1.7 Danh mục các sản phẩm 20 8 Hình 1.8 Bài đăng thông tin về sản phẩm 21 9 Hình 1.9 Bài đăng báo giá 22 10 Hình 1.10 Bài đăng tin tức 22 11 Hình 1.11 Danh sách các công trình khác 23 12 Hình 4.1 Lượt đồ tổng quan usecase 30 13 Hình 5.1 Lượt đồ cơ sở dữ liệu 59 Các bản dữ liệu có mối quan hệ với 14 Hình 5.2 64 nhau 15 Hình 5.3 Trang chủ website Viko 64 16 Hình 5.4 Mục giới thiệu trên trang chủ 65 17 Hình 5.5 Mục sản phẩm nổi bật trên trang chủ 66 2
  11. Mục tiêu chí hoạt động trên trang 18 Hình 5.6 66 chủ Mục dự án đã thực hiên trên trang 19 Hình 5.7 67 chủ Mục khách hàng nói về chúng tôi 20 Hình 5.8 67 trên trang chủ 21 Hình 5.9 Mục liên hệ trên trang chủ 68 22 Hình 5.10 Trang danh sách sản phẩm 68 Mục lọc sản phẩm trên trang danh 23 Hình 5.11 69 sách sản phẩm 24 Hình 5.12 Trang chi tiết sản phẩm 69 Mục bài viết trên trang chi tiết sản 25 Hình 5.13 70 phẩm Mục nhận xét cùng mục sản phẩm 26 Hình 5.14 71 cùng loại trên trang chi tiết sản phẩm 27 Hình 5.15 Trang danh sách dự án đã thưc hiện 71 Mục các danh sách dự án đã thực 28 Hình 5.16 72 hiện trên trang dự án đã thực hiện 29 Hình 5.17 Trang chi tiết dự án 72 30 Hình 5.18 Mục bài viết trên trang chi tiết dự án 73 Mục các dự án khác trên trang chi 31 Hình 5.19 73 tiết dự án 32 Hình 5.20 Trang đăng nhập Admin 73 33 Hình 5.21 Trang Admin 74 34 Hình 5.22 Trang thêm loại sản phẩm 74 35 Hình 5.23 Trang danh sách loại sản phẩm 75 3
  12. 36 Hình 5.24 Trang sửa loại sản phẩm 75 37 Hình 5.25 Trang thêm sản phẩm 76 38 Hình 5.26 Trang danh sách sản phẩm 77 39 Hình 5.27 Trang sửa sản phẩm 78 40 Hình 5.28 Trang thêm dự án đã thực hiện 80 41 Hình 5.29 Trang danh sách dự án đã thực hiện 81 42 Hình 5.30 Trang sửa dự án đã thực hiện 82 43 Hình 5.31 Trang cập nhật thông tin công ty 83 44 Hình 5.32 Trang danh sách yêu cầu báo giá 84 45 Hình 5.33 Trang sửa thông tin tài khoản 84 Trang báo lỗi Not Found khi không 46 Hình 5.34 84 tìm thấy trang 4
  13. LỜI MỞ ĐẦU 1. Tính cấp thiết của đề tài Theo thống kê mới nhất, tính đến đầu năm 2019, Việt Nam đã có hơn 60 triệu người sử dụng internet, chiếm hơn 60% dân số. Và trong tương lai con số này sẽ vẫn tiếp tục tăng lên không ngừng. Có thể nói đối với các nhà kinh doanh thì môi trường internet chính là một môi trường chứa đầy khách hàng tiềm năng nhất mà mọi doanh nghiệp hay tổ chức nào cũng đều thèm khát. Do đó để khai thác tiềm năng này một cách tốt nhất thì điều không thể thiếu đó chính là đầu tư, phát triển cho riêng mình một Website giới thiệu, quảng bá bản thân doanh nghiệp hoặc bất kỳ tổ chức nào. 2. Tình hình nghiên cứu Có thể nói việc nghiên cứu và phát triển website đã không còn là một vấn đề xa lạ trong kỷ nghiên 4.0 ngày này. Và đặc biệt trong thời đại kinh tế cạnh tranh thì các website phục vụ trong mục đích kinh doanh, quảng bá luôn được ưu tiên phát triển hàng đầu. Điều này có thể dễ dàng thấy thông qua các website của các thương hiệu nổi tiếng hàng đầu trong lĩnh vực kinh doanh như samsung.com, lazada.vn, sony.com.vn, Những website của các thương hiệu này luôn được trao chuốt một cách kĩ lưỡng. Ngoài ra không chỉ những các thương hiệu lớn mới có riêng cho mình một website để quảng bá thương hiệu của mình, mà còn hàng ngàn các công ty, doanh nghiêp lớn nhỏ đều sỡ hữu một website để quảng bá thương hiệu của mình đến mọi người. 5
  14. 3. Mục đích nghiên cứu Đề tài có mục đích xây dựng website giới thiệu công ty giúp đưa tới khách hàng những hình ảnh, thông tin một cách đầy đủ và rõ nét về công ty đó. Qua đó tạo được thêm nhiều ưu thế trên môi trường marketing. 4. Nhiệm vụ nghiên cứu Để thực hiện được đề tài một cách trọn vẹn phải trãi qua nhiều giai đoạn nghiên cứu, tìm hiểu, chọn lọc và cuối cùng mới đến công đoạn bắt tay vào xây dựng nên một website. Đầu tiên việc tìm hiểu về cơ sở lý thuyết để tạo ra một website là điều tất yếu. Kế đến cần phải khảo sát thực tế xem website có phù hợp cũng như đồng thời tham khảo những website tương tự. Tiếp đến phải xây dựng mô hình về website như các chức năng, ràng buộc, Và cuối cùng là công việc xây dựng website hoàn chỉnh. 5. Các kết quả đạt được của đề tài Thông qua đề tài sẽ mang đến những kiến thức và cách xây dựng lên một website hoàn chỉnh. Đồng thời website được xây dựng trong đề tài sẽ đạt được một cách đầy đủ và tốt nhất các mục tiêu ban đầu đề. 6
  15. CHƯƠNG 1: CƠ SỞ LÝ THUYẾT VÀ KHẢO SÁT 1.1 HTML,CSS và JavaScript − HTML, CSS và JavaScript là những khái niệm không hề xa lạ với những người lập trình website chuyên nghiệp. Chúng chính là nền tảng không thể thiếu để xây dựng,tô vẽ và làm sống động cho chính những trang web. Và vì lẽ đó mà HTML, CSS, JavaScript là những khái niệm mà bắt buộc ai cũng phải có khi muốn bước chân vào con đường phát triển website. 1.1.1 HTML là gì? − HTML là viết tắt của HyperText Markup Language (ngôn ngữ đánh dấu siêu văn bản) dùng mô tả cấu trúc của các trang Web và tạo ra các loại tài liệu có thể xem được trong trình duyệt. − HTML là cốt lõi của mọi trang web. Mỗi trang web được tạo thành từ một loạt các thẻ HTML mà chúng biểu thị từng loại nội dung trên trang. Mỗi loại nội dung trên trang được “bọc”, tức là được bao quanh bởi các thẻ HTML. − HTML không phải là ngôn ngữ lập trình, đồng nghĩa với việc nó không thể tạo ra các chức năng “động” được. Nó chỉ giống như Microsoft Word, dùng để bố cục và định dạng trang web. 1.1.2 CSS là gì? − CSS (viết tắt của Cascading Style Sheets) là một ngôn ngữ định dạng được sử dụng để mô tả trình bày các trang Web, bao gồm màu sắc, cách bố trí và phông chữ. Nó cho phép hiển thị nội dung tương thích trên các loại thiết bị có kích thước màn hình khác nhau, chẳng hạn như màn hình lớn, màn hình nhỏ, hoặc máy in. 7
  16. − Trong khi HTML là cấu trúc cơ bản của trang web. CSS mang lại cho trang web của bạn phong cách mà bạn muốn. CSS gần như tạo nên bộ mặt của một website. − Cũng giống như HTML, CSS không phải là một ngôn ngữ lập trình. 1.1.3 JavaScript là gì? − JS (viết tắt của Javascript) là một nền tảng (cross-platform), ngôn ngữ kịch bản hướng đối tượng (object-oriented). Nó là một ngôn ngữ nhỏ và nhẹ. Chạy trong môi trường máy chủ lưu trữ (ví dụ: trình duyệt web), JavaScript có thể được kết nối với các đối tượng của môi trường để cung cấp kiểm soát chương trình đối với chúng. − JavaScript là ngôn ngữ lập trình dựa trên logic. Nó có thể được sử dụng để sửa đổi nội dung trang web. Và khiến nó hoạt động theo nhiều cách khác nhau để đáp ứng với hành động của người dùng. Các cách sử dụng phổ biến cho JavaScript bao gồm các hộp xác nhận, kêu gọi hành động và thêm các danh tính mới vào thông tin hiện có. 1.2 Bootstrap 1.2.1 Bootstrap là gì? − Bootstrap là một front-end framework miễn phí giúp quá trình phát triển web nhanh chóng và dễ dàng hơn. − Bootstrap bao gồm các mẫu thiết kế dựa trên HTML và CSS như typography, forms, buttons, tables, navigation, modals, image carousels cũng như các plugin JavaScript tùy chọn. − Bootstrap cũng cung cấp cho bạn khả năng tạo ra các responsive designs một cách dễ dàng. 8
  17. 1.2.2 Tại sao nên dùng Bootstrap? − Dễ sử dụng: Bất kỳ ai có kiến thức cơ bản về HTML và CSS đều có thể bắt đầu sử dụng Bootstrap. − Các tính năng đáp ứng (Responsive features): responsive CSS của Bootstrap điều chỉnh cho điện thoại, máy tính bảng và máy tính để bàn. − Khả năng tương thích trình duyệt: Bootstrap tương thích với tất cả các trình duyệt hiện đại (Chrome, Firefox, Internet Explorer, Edge, Safari và Opera). − Tiết kiệm thời gian: Bootstrap giúp cho lập trình viên thiết kế giao diện website tiết kiệm rất nhiều thời gian và công sức, bởi các thư viện của Bootstrap có nhiều đoạn mã có thể sẵn sàng áp dụng ngay vào website. Khi đó sẽ tiết kiệm được rất nhiều thời gian để tự viết code cho giao diện website của bản thân. 1.3 JQuery 1.3.1 JQuery là gì? − JQuery là thư viện được viết từ JavaScript, jQuery giúp xây dựng các chức năng bằng Javascript dễ dàng, nhanh và giàu tính năng hơn. jQuery được tích hợp nhiều module khác nhau. Từ module hiệu ứng cho đến module truy vấn selector. jQuery được sử dụng đến 99% trên tổng số website trên thế giới. − JQuery không phải là một ngôn ngữ lập trình riêng biệt mà hoạt động liên kết với JavaScript. Với jQuery, bạn có thể làm được nhiều việc hơn mà lại tốn ít công sức hơn. 1.3.2 Tại sao nên dùng jQuery? − Gọn nhẹ: jQuery là một thư viện khá gọn nhẹ – có kích cỡ khoảng 19KB. 9
  18. − Tương thích đa nền tảng: Nó tự động sửa lỗi và chạy được trên mọi trình duyệt phổ biến như Chrome, Firefox, Safari, MS Edge, IE, Android và iOS. − Dễ dàng tạo Ajax: Nhờ thư viện jQuery, code được viết bởi Ajax có thể dễ dàng tương tác với server và cập nhật nội dung tự động mà không cần phải tải lại trang. − Xử lý nhanh nhạy thao tác DOM: jQuery giúp lựa chọn các phần tử DOM để traverse (duyệt) một cách dễ dàng, và chỉnh sửa nội dung của chúng bằng cách sử dụng Selector mã nguồn mở, mà còn được gọi là Sizzle. − Đơn giản hóa việc tạo hiệu ứng: Giống với code snippet có hiệu ứng animation, nó phủ các dòng code và bạn chỉ việc thêm biến/nội dung vào thôi. − Hỗ trợ tốt phương thức sự kiện HTML: Xử lý sự kiện − jQuery xử lý các sự kiện đa dạng mà không làm cho HTML code trở nên lộn xộn với các Event Handler. 1.4 Ajax 1.4 Ajax là gì? − AJAX là chữ viết tắt của Asynchronous JavaScript and XML. Đây là một công nghệ giúp chung ta tạo ra những Web động mà hoàn toàn không reload lại trang. − Cả JavaScript và XML đều hoạt động bất đồng bộ trong AJAX. Kết quả là, nhiều ứng dụng web có thể sử dụng AJAX để gửi và nhận data từ server mà không phải toàn bộ trang. 10
  19. 1.4.2 Tại sao nên dùng Ajax? − Callbacks: Ajax được sử dụng để thực hiện một cuộc gọi lại. AJAX thực hiện việc truy xuất và / hoặc lưu dữ liệu mà không gửi toàn bộ trang trở lại máy chủ. Bằng cách gửi lại một phần trang web đến máy chủ, việc sử dụng mạng được giảm thiểu và các hoạt động diễn ra nhanh hơn. Trong các trang web băng thông hạn chế, điều này có thể cải thiện đáng kể hiệu suất mạng. Dữ liệu được gửi đến và đi từ máy chủ một cách tối thiểu. − Thực hiện các cuộc gọi không đồng bộ: Ajax cho phép bạn thực hiện các cuộc gọi không đồng bộ đến một máy chủ web. Điều này cho phép trình duyệt của người dùng tránh phải chờ tất cả dữ liệu đến trước khi cho phép người dùng hành động một lần nữa. − Thân thiện với người dùng: Vì không phải post lại trang lên server, các ứng dụng hỗ trợ Ajax sẽ luôn nhanh hơn và thân thiện với người dùng hơn. − Tăng tốc độ: Mục đích chính của Ajax là cải thiện tốc độ, hiệu suất và khả năng sử dụng của một ứng dụng web. Một ví dụ tuyệt vời của Ajax là tính năng xếp hạng phim trên Netflix. Người dùng đánh giá một bộ phim và xếp hạng cá nhân của họ cho bộ phim đó sẽ được lưu vào cơ sở dữ liệu của họ mà không cần chờ trang làm mới hoặc tải lại. 1.5 Lararel 1.5.1 Laravel là gì? − Là một framework PHP có mã nguồn mở miễn phí, giúp xây dựng các ứng dụng theo mô hình MVC (Model - View – Controller) một cách nhanh chóng, được tạo ra bởi một lập trình viên kỳ cựu từng làm .NET 11
  20. đó là Taylor Otwell. Được phát hành lần đầu vào ngày 9 tháng 6 năm 2011. Các phiên bản của laravel đến tháng 4 năm 2020 − Trước đây Laravel có tên là Bootplant sau đó thì đổi thành là Laravel, nguồn gốc tên bắt nguồn từ tên một tòa lâu đài ở Narnia, một vùng đất không có thật, mà nó ở trong một thế giới được tưởng tượng ra 12
  21. bởi nhà văn Clive Staples Lewis, và viết thành cuốn tiểu thuyết “Biên niên sử Narnia” [4] rất nổi tiếng được dựng thành phim. Tòa lâu đài có tên là Paravel đọc lái đi sẽ thành Laravel, mục đích của Taylor Otwell là mong muốn đứa con tinh thần Laravel phát triển một cách mạnh mẽ và vững trải như tòa lâu đài. Và rồi đến tận bây giờ thì Laravel vẫn luôn là một trong những framework tốt nhất của PHP. 1.5.2 Tại sao nên dùng Laravel? − Laravel có thể xây dựng hệ thống các ứng dụng web phức tạp với hiệu năng cao. Cho dù laravel rất đơn giản và dễ dàng cho người mới tiếp cận với framework PHP nhưng vẫn đảm bảo hệ thống có kiến trúc thống nhất và khoa học. − Cộng đồng Laravel rất lớn trên Laracast, bạn có thể tìm câu trả lời cho những vấn đề, tình huống mà bạn thắc mắc hay là không biết trong Laravel. Không những thế các tài nguyên liên quan đến Laravel cũng rất đa dạng, dễ sử dụng. Tác giả của framework này -Taylor Otwell cũng đã biên soạn ra tài liệu để cho các lập trình viên khám phá và trải nghiệm. − Có tích hợp công cụ dòng lệnh là Artisan, hỗ trợ rất nhiều trong việc phát triển ứng dụng: tối ưu hóa ứng dụng, migrate dữ liệu, tạo các template, controller, − Trong Laravel có một bộ máy template rất hay, đó là blade template, giúp thực hiện làm việc tương tác giữa PHP và HTML đơn giản hơn, tách biệt hơn giữa mã hiển thị và mã logic nghiệp, cái mà trước đó chỉ có thể biết đến ở .NET hoặc Java. Blade template còn có thể kế thừa một template khác và có thể còn script js, jquery − Laravel sử dụng gói thư viện Webpack kết hợp với npm, yarn nhằm giúp bạn tự động hóa thay vì build thủ công các ứng dụng và triển 13
  22. khai sản phẩm. Từ đó có thể thấy được Laravel hỗ trợ việc các đặt các gói thư viện và sử dụng nhằm tạo ra các tính năng tuyệt vời. − Laravel rất an toàn trong việc chỉn chu bảo mật với CSRF tokens. Với cách kiểm tra mã CSRF trong mỗi POST, về cơ bản là đã bảo vệ chương trình khi bị cố tình thay đổi bản chất, kể cả từ POST đến GET. Ngoài ra Laravel còn cung cấp sẵn các Middleware cho trước hoặc lập trình viên có thể được hỗ trợ để tạo riêng cho mình một Middleware nhằm mục đích tăng thêm độ bảo mật cho ứng dụng website. − Laravel hỗ trợ lập trình theo mô hình MVC khá mạnh mẽ. Ngoài các thành phần chính Model, View, Controller thì Routes được sử dụng định tuyến người dùng theo đúng Urls. − Laravel luôn thay đổi, cập nhật trong các phiên bản, luôn tìm kiếm những tính năng hay, những gói thư viện tốt và hữu ích để tích hợp vào. Cách thức hoạt động MVC trong Laravel 14
  23. 1.6 PHP 1.6.1 PHP là gì? − PHP khởi đầu như là một dự án mã nguồn mở nhỏ, nhưng theo đà phát triển, ngày càng nhiều người thấy rằng nó càng ngày càng hữu ích. PHP được phát triển từ một sản phẩm có tên là PHP/FI. PHP/FI do Rasmus Lerdorf tạo ra năm 1994, ban đầu được xem như là một tập con đơn giản của các mã kịch bản Perl để theo dõi tình hình truy cập đến bản sơ yếu lý lịch của ông trên mạng. Ông đã đặt tên cho bộ mã kịch bản này là "Personal Home Page Tools". Khi cần đến các chức năng rộng hơn, Rasmus đã viết ra một bộ thực thi bằng C lớn hơn để có thể truy vấn tới Database và giúp cho người sử dụng phát triển các ứng dụng web đơn giản. Rasmus đã quyết định công bố mã nguồn của PHP/FI cho mọi người xem, sử dụng cũng như sửa các lỗi có trong nó, đồng thời cải tiến mã nguồn. − PHP viết hồi qui của "PHP: Hypertext Preprocessor". − PHP là ngôn ngữ lập trình kịch bản viết cho máy chủ mà được nhúng trong HTML. Nó được sử dụng để quản lý nội dụng động, Database, Session tracking, Nó được tích hợp với một số Database thông dụng như MySQL, PostgreSQL, Oracle, Sybase, Informix, và Microsoft SQL Server. − PHP thực thi rất tuyệt vời, đặc biệt khi được biên dịch như là một Apache Module trên Unix side. MySQL Server, khi được khởi động, thực thi các truy vấn phức tạp với các tập hợp kết quả khổng lồ trong thời gian Record-setting. − PHP hỗ trợ một số lượng rộng rãi các giao thức lớn như POP3, IMAP, và LDAP. PHP4 bổ sung sự hỗ trợ cho Java và các cấu trúc đối tượng phân phối (COM và CORBA). 15
  24. − Cú pháp PHP là giống C. Những ngôn ngữ lập trình phổ biến từ năm 1965 – 2019 1.6.2 Tại sao nên dùng PHP − Hiện nay, có hàng ngàn ngôn ngữ lập trình có sẵn nhưng chỉ có vài ngôn ngữ phổ biến và được nhiều người tin dùng. 1 trong các ngôn ngữ lập trình phổ biến nhất đó là PHP. Đây là 1 ngôn ngữ được thiết kế để phục vụ cho việc phát triển web và được cài đặt trên 20 triệu website, 1 triệu máy chủ web. − Ngôn ngữ ASP cũng là 1 ngôn ngữ lập trình được xem là 1 trong những đối thủ cạnh tranh của PHP, 2 ngôn ngữ này đều được dùng cho việc tạo website, linh động hơn so với web tĩnh dùng ngôn ngữ HTML, cho phép người dùng tương tác và trao đổi thông tin. − Hiện nay, có hàng ngàn ngôn ngữ lập trình có sẵn nhưng chỉ có vài ngôn ngữ phổ biến và được nhiều người tin dùng. 1 trong các ngôn ngữ lập trình phổ biến nhất đó là PHP. Đây là 1 ngôn ngữ được thiết kế 16
  25. để phục vụ cho việc phát triển web và được cài đặt trên 20 triệu website, 1 triệu máy chủ web. − Ngôn ngữ ASP cũng là 1 ngôn ngữ lập trình được xem là 1 trong những đối thủ cạnh tranh của PHP, 2 ngôn ngữ này đều được dùng cho việc tạo website, linh động hơn so với web tĩnh dùng ngôn ngữ HTML, cho phép người dùng tương tác và trao đổi thông tin. So sánh giữa ASP và PHP 1.7 Khảo Sát Hiện Trạng 1.7.1 Khảo sát thực tế − Hiện nay, kinh tế ngày càng phát triển dẫn theo đó xuất hiện ngày càng nhiều những doanh nghiệp, công ty luôn trong trạng thái cạnh tranh nhau trong việc kinh doanh, buôn bán. Chính vì lẽ đó để luôn đứng vững và phát triển trên thị trường, nhiều doanh nghiệp, công ty đã đặt Marketing là yếu tố chiến lược hàng đầu. Và một trong những chiến lược quảng bá không thể thiếu trong thời đại bùng nổ internet ngày nay đó chính là có riêng cho mình một website giới thiệu hình ảnh, thông tin của công ty hoặc doanh nghiệp. 17
  26. − Với thời đại 4.0 như ngày nay thì việc tìm kiếm trên website trực tuyến sẽ dễ dàng hơn, nhiều sự lựa chọn hơn. Chính vì vậy, mà các trang web được mở ra càng nhiều và đa dạng. Với những thiết bị như Smartphone, Laptop, và những thiết bị chạy trên nền tảng có thể kết nối mạng mà hầu hết mọi người đều có bên mình thì sẽ dễ dàng truy cập và tìm ra những thứ mình muốn. 1.7.2 Khảo sát các website tương tự − Nắm bắt được nhu cầu đó, nhiều công ty đã mở cho mình một website để tự giới thiệu, quảng bá về hình ảnh của họ và trong đó tandaithanh.vn.net là một trong những website tiêu biểu hàng đầu. tandaithanh.vn.net đã thành công trong việc đưa tới khách hàng của họ những cái nhìn rõ nét nhất về hình ảnh công ty, thông tin sản phẩm mà họ cung cấp cùng thêm nhiều tin tức quan trọng khác. − tandaithanh.vn.net là một website về cung cấp các loại cửa kính với giao diện thân thiện cùng cách bố trí nội dung hài hào tạo cho người xem cảm giác thoải mái đồng thời dễ dàng tìm kiếm được thông tin mong muốn. *Phân tích website tandaithanh.vn.net: − Trang chủ: + Logo website, tên công ty. + Thanh điều hướng. + Silde tiêu đề hình ảnh sản phẩm. 18
  27. Slide hình ảnh sản phẩm + Các danh mục: − Sản Phẩm Của Chúng Tôi: Cửa sổ nhôm kính, cửa sổ kính cường lực, kính ốp trang trí, cửa đi một cánh, − Giới Thiệu: Cửa kính đẹp, lan can đẹp, cầu thang kính, kính cường lực ngoài trời. − Công Trình Tiêu Biểu: Lan can kính quận Tân Phú, công trình Bình Tiên quận 6, công trình cách mạng tháng 8, công trình Bùi Hữu Nghĩa quận Bình Thạnh, − Tin tức: Ưu điểm của cửa nhôm kính so với cửa truyền thống, ưu điểm vượt trội của cửa nhôm kính sơn tĩnh điện, mẫu cửa nhôm kính đẹp cho công trình của bạn, − Chân Trang: Các thông tin liên hệ và địa chỉ của công ty. 19
  28. + Các chức năng: tìm kiếm, xem thêm chi tiết của từng bài đăng, gửi yêu cầu tới công ty. Mẫu gửi thông tin yêu cầu tới công ty − Trang sản phẩm: Danh mục các sản phẩm. Danh mục các sản phẩm 20
  29. − Trang thông tin về sản phẩm: + Các danh mục: − Thông Tin Sản Phẩm: Bài đăng thông tin về sản phẩm, các hình ảnh liên quan về sản phẩm. − Sản Phẩm Tương Tự: Danh sách các sản phẩm tương tự. Bài đăng thông tin về sản phẩm 21
  30. − Trang báo giá: Thông tin báo giá của từng loại sản phẩm Bài đăng báo giá − Trang tin tức: Danh mục các tin tức. − Trang chi tiết tin tức: + Các danh mục: − Tin Tức: Bài đăng về tin tức. − Các tin tức khác: Danh sách các tin khác. Bài đăng tin tức 22
  31. − Trang công trình đã hoàn thiện: Danh mục các công trình đã hoàn thiện. − Trang thông tin về công trình: + Các danh mục: − Thông Tin Công Trình: Bài đăng thông tin về công trình, các hình ảnh về công trình đã hoàn thiện. − Danh Sách Các Công Trình Khác: Danh sách các công trình khác. Danh sách các công trình khác 23
  32. CHƯƠNG 2: TỔNG QUAN CHỨC NĂNG WEBSITE 2.1 Quan Điểm Của Sản Phẩm − Giao diện thân thiện, đẹp mắt. − Dễ sử dụng. − Giúp người dùng tìm kiếm thông tin dễ dàng. − Tính bảo mật website cao. 2.2 Chức Năng Sản Phẩm − Xem tin. − Tìm kiếm thông tin về sản phẩm. − Gửi yêu cầu nhận báo giá. − Lọc các loại sản phẩm mong muốn. − Đánh giá, nhận xét bài đăng về sản phẩm. − Các chức năng riêng biệt dành cho admin như: quản lý bài đăng, quản lý tài khoản, nhận danh sách yêu cầu từ khách hàng. 2.3 Người Dùng − Admin: Quản lí tất cả các tin đăng trên website, nhận thông báo yêu cầu của khách hàng và tự quản lí tài khoản như cập nhập thông tin, đổi mật khẩu. − Guest: Xem tin, tìm kiếm sản phẩm, lọc sản phẩm, nhận xét và gửi yêu cầu đến công ty. 24
  33. 2.4 Các Ràng Buộc − Guest chỉ thực hiện được 5 chức năng: Xem tin, tìm kiếm sản phẩm, lọc sản phẩm, nhận xét tin và gửi yêu cầu. Không thể thực hiện các hoạt động dành cho admin. 25
  34. CHƯƠNG 3: YÊU CẦU CHỨC NĂNG WEBSITE 3.1 Xem tin − Có thể xem các thông tin về công ty theo từng loại chủ đề khác nhau. 3.2 Tìm kiếm sản phẩm − Có thể dễ dàng tìm kiếm thông tin về sản phẩm thông qua việc nhập từ khóa trên thanh tìm kiếm. 3.3 Lọc sản phẩm − Dễ dàng lọc ra các sản phẩm thuộc những loại mong muốn một cách nhanh chóng. 3.4 Gửi yêu cầu nhận báo giá − Hỗ trợ gửi yêu cầu dưới dạng tin nhắn đến công ty. 3.5 Nhận xét bài viết về sản phẩm − Công khai nhận xét tất cả các bài đăng về sản phẩm của công ty. 3.6 Đăng nhập/đăng xuất + Đăng Nhập: − Dành cho Admin: Đăng nhập để sử dụng tất cả quyền hạn cho việc quản lý website. + Đăng Xuất: − Dành cho Admin: Thoát khỏi trang quản trị và quay trở về trang đăng nhập. Không thể truy cập vào trang quản trị theo đường link url khi chưa đăng nhập. 26
  35. 3.7 Quản lý các tin đăng trên website − Dành cho Admin: Thực hiện các thao tác quản lý các tin đăng như: xem, thêm, sửa, xóa. 3.8 Nhận các thông báo yêu cầu từ khách hàng − Dành cho Admin: Nhận danh sách những yêu cầu từ khách hàng, thông báo yêu cầu mới dưới dạng hộp thư. 3.9 Quản lý thông tin tài khoản − Dành cho Admin: Quản lý tài khoản admin như thay đổi thông tin, đổi mật khẩu. 27
  36. CHƯƠNG 4: MÔ HÌNH USECASE 4.1 Tác nhân Bảng các tác nhân và quyền của tác nhân trong UseCase STT Các Chức Năng Chính Admin Guest 1 Xem các thông tin về công ty X X 2 Đăng nhập/Đăng xuất X 3 Tìm kiếm sản phẩm X X 4 Lọc sản phẩm theo loại X X 5 Nhận xét bài viết về sản phẩm X X 6 Gửi yêu cầu nhận báo giá X X 7 Quản lý các tin đăng X 8 Nhận thông báo yêu cầu từ khách X hàng 9 Quản lý thông tin tài khoản X 4.2 Các yêu cầu chức năng Bảng các yêu cầu chức năng hệ thống Chức Năng Hệ Thống Yêu Cầu Chức Năng Ký Hiệu Đăng nhập/Đăng xuất Đăng nhập UC_1.1 Đăng xuất UC_1.2 Xem Tin Đăng Xem các tin được đăng trên trang chủ UC_2.1 Xem chi tiết danh mục tin UC_2.2 Xem chi tiết tin đăng UC_2.3 28
  37. Hiển thị tiêu đề các tin liên quan UC_2.4 Tìm/Lọc Sản Phẩm Tìm kiếm sản phẩm UC_3.1 Lọc sản phẩm UC_3.2 Nhận Xét Bài Đăng Đăng nhận xét UC_4.1 Gửi Yêu Cầu Báo Giá Gửi yêu cầu nhận báo giá sản phẩm UC_5.1 Quản Lý Tài Khoản Cập nhập thông tin UC_6.1 Thay đổi mật khẩu UC_6.2 Nhận Thông Báo Yêu Cầu Nhận thông báo yêu cầu mới UC_7.1 Xem danh sách các yêu cầu UC_7.2 Xem chi tiết yêu cầu UC_7.3 Quản Lý Tin Đăng Xem danh sách tin đăng UC_8.1 Thêm tin đăng UC_8.2 Sửa tin đăng UC_8.3 Xóa tin đăng UC_8.4 29
  38. 4.3 Lược Đồ Use Case Lượt đồ tổng quan usecase 30
  39. 4.4 Chi Tiết Các Use Case Bảng chi tiết các UseCase Use Case ID UC_1.1 Name Đăng nhập Goal Đăng nhập thành công với tài khoản được cấp trước Actors Admin Pre-conditions Post-conditions Flow of events Basic flow (Thành công) 1. Hệ thống yâu cầu người truy cập cung cấp thông tin đăng nhập đã được cấp từ trước là tên đăng nhập và mật khẩu. 2. Sau khi người truy cập điền đẩy đủ, sau đó nhấn vào nút đăng nhập. 3. Hệ thống sẽ so sánh dữ liệu nhập vào với tên đăng nhập và mật khẩu được mã hóa với dữ liệu đã được cấp trong Database. Nếu dữ liệu được cung cấp chính xác => Đăng nhập thành công, hệ thống sẽ trả về trang quản trị admin. Alternativeflow (Thất bại) 31
  40. 1. Hệ thống yâu cầu người truy cập cung cấp thông tin đăng nhập đã được cấp từ trước là tên đăng nhập và mật khẩu. 2. Sau khi người truy cập điền đẩy đủ sau, đó nhấn vào nút đăng nhập. 3. Hệ thống sẽ so sánh dữ liệu nhập vào với tên đăng nhập và mật khẩu được mã hóa với dữ liệu đã được cấp trong Database. Nếu dữ liệu được cung cấp sai, không trùng khớp. Hệ thống sẽ trả lại trang đăng nhập với thông báo “Tên Đăng Nhập Hoặc Mật Khẩu Không Đúng”. Extension Không có Use Case ID UC_1.2 Name Đăng xuất Goal Đăng xuất tài khoản thành công chỉ khi đã đăng nhập Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow 32
  41. (Thành công) 1. Người dùng nhấp vào logo avatar người dùng. 2. Hệ thống sẽ hiện ra một danh sách chức năng trong đó có nút đăng xuất sau đó nhấp vào đăng xuất. 3. Hệ thống sẽ lập tức kết thúc section và quay lại trang đăng nhập. Alternativeflow 1. Không có. Nút đăng xuất chỉ hiện lên khi người try (Thất bại) cập đã đăng nhập thành công sau đó Extension Không có Use Case ID UC_2.1 Name Xem các tin được đăng trên trang chủ Goal Các tin đăng được in lên trang chủ Actors Guest, Admin Pre-conditions Post-conditions Flow of events Basic flow (Thành công) 1. Truy cập vào đường dẫn Website. 2. Tất cả tin đăng ở trang chủ với sắp xếp theo từng mục tương ứng với loại tin đó. Một số tin đăng sẽ xuất hiện như tiêu đề tin để dẫn đến phần chi tiết của tin. Một số 33
  42. tin xuất hiện đóng vai trò làm danh mục cho những tin tương ứng. Còn lại sẽ xuất hiện dưới dạng bài viết ngay trên trang. Alternativeflow 1. Không có tin đăng nào được hiển thị (Thất bại) Extension Không có Use Case ID UC_2.2 Name Xem chi tiết mục tin Goal Chuyển hướng đến trang chứa các tiêu đề tin thuộc mục tin được chọn Actors Guest, Admin Pre-conditions Post-conditions Flow of events Basic flow (Thành công) 1. Truy cập vào đường dẫn Website. 2. Nhấp vào một mục tin bất kì trong danh sách mục tin. 3. Hệ thống chuyển hướng đến trang chứa các tiêu đề tin thuộc mục tin được chọn. Alternativeflow 34
  43. (Thất bại) 1. Truy cập vào đường dẫn Website. 2. Nhấp vào một mục tin bất kì trong danh sách mục tin. 3. Hệ thống ko có phản hồi. Hoặc chuyển hướng lỗi. Extension Không có Use Case ID UC_2.3 Name Xem chi tiết tin đăng Goal Chuyển hướng đến trang chi tiết tin đăng với đầy đủ thông tin Actors Guest, Admin Pre-conditions Post-conditions Flow of events Basic flow (Thành công) 1. Truy cập vào đường dẫn Website. 2. Nhấp vào một tiêu đề tin bất kỳ. 3. Hệ thống sẽ chuyển hướng tới trang của tin vừa chọn. Với đầy đủ thông tin chi tiết. Alternativeflow 35
  44. (Thất bại) 1. Truy cập vào đường dẫn Website. 2. Nhấp vào một tin bất kỳ. 3. Hệ thống ko có phản hồi. Hoặc chuyển hướng lỗi. Extension Không có Use Case ID UC_2.4 Name Hiển thị tiêu đề các tin liên quan Goal Hiển thị danh sách các tiêu đề tin có cùng loại mục tin với trang chi tiết tin đang truy cập Actors Guest, Admin Pre-conditions Post-conditions Flow of events Basic flow (Thành công) 1. Truy cập vào đường dẫn Website. 2. Nhấp vào một tiêu đề tin bất kỳ. 3. Hệ thống sẽ chuyển hướng tới trang của tin vừa chọn. Với đầy đủ thông tin chi tiết cùng danh sách các tiêu đề tin có cùng loại mục với tin được truy cập. 36
  45. Alternativeflow (Thất bại) 1. Truy cập vào đường dẫn Website. 2. Nhấp vào một tin bất kỳ. 3. Hệ thống sẽ chuyển hướng tới trang của tin vừa chọn. Với đầy đủ thông tin chi tiết nhưng không hiển thị danh sách các tiêu đề tin có cùng loại mục với tin được truy cập hoặc danh sách không đúng. Extension Không có Use Case ID UC_3.1 Name Tìm kiếm sản phẩm Goal Hiển thị danh sách sản phẩm tương ứng với từ khóa được nhập Actors Guest, Admin Pre-conditions Post-conditions Flow of events Basic flow (Thành công) 1. Truy cập vào đường dẫn Website. 2. Chọn công cụ tìm kiếm sản phẩm. 37
  46. 3. Nhập từ khóa sản phẩm muốn tìm vào thanh tìm kiếm. 4. Hệ thống trả về danh sách tên các sản phẩm tưng ứng với từ khóa được cung cấp. Alternativeflow (Thất bại) 1. Truy cập vào đường dẫn Website. 2. Chọn công cụ tìm kiếm sản phẩm. 3. Nhập từ khóa sản phẩm muốn tìm vào thanh tìm kiếm. 4. Hệ thống không phản hồi, hoặc phản hồi nhưng ko trả lại dữ liệu đúng. Extension Không có Use Case ID UC_3.2 Name Lọc sản phẩm Goal Lọc ra danh sách sản phẩm theo những chủ đề được chọn Actors Guest, Admin Pre-conditions Post-conditions Flow of events 38
  47. Basic flow (Thành công) 1. Truy cập vào đường dẫn Website. 2. Chọn mục loại sản phẩm. 3. Hệ thống điều hướng đến trang danh sách loại sản phẩm. 4. Tích chọn vào những chủ đề muốn lọc. 5. Hệ thống sẽ trả về danh sách các sản phẩm tương ứng với những chủ đề được chọn. Alternativeflow (Thất bại) 1. Truy cập vào đường dẫn Website. 2. Chọn mục loại sản phẩm. 3. Hệ thống điều hướng đến trang danh sách loại sản phẩm. 4. Tích chọn vào những chủ đề muốn lọc. 5. Hệ thống không phản hồi, hoặc phản hồi nhưng ko trả lại dữ liệu đúng. Extension Không có 39
  48. Use Case ID UC_4.1 Name Đăng nhận xét Goal Đăng nhận xét về một bài đăng sản phẩm bất kỳ Actors Guest, Admin Pre-conditions Post-conditions Flow of events Basic flow (Thành công) 1. Truy cập vào đường dẫn Website. 2. Nhấp vào một tiêu đề tin bất kỳ. 3. Hệ thống sẽ chuyển hướng tới trang chi tiết tin đăng. 4. Chọn phần nhận xét. 5. Hệ thống sẽ yêu cầu điền đầy đủ thông tin như là tên người nhận xét và nội dung nhận xét. 6. Sau khi điền đầy đủ thông tin, nhấn nút nhận xét. 7. Hệ thống sẽ đăng bài nhận xét trong trang chi tiết tin đăng đó. 40
  49. Alternativeflow (Thất bại) 1. Truy cập vào đường dẫn Website. 2. Nhấp vào một tiêu đề tin bất kỳ. 3. Hệ thống sẽ chuyển hướng tới trang chi tiết tin đăng. 4. Chọn phần nhận xét. 5. Hệ thống sẽ yêu cầu điền đầy đủ thông tin như là tên người nhận xét và nội dung nhận xét. 6. Sau khi điền đầy đủ thông tin, nhấn nút nhận xét. 7. Hệ thống không đăng bài nhận xét. Extension Không có Use Case ID UC_5.1 Name Gửi yêu cầu nhận báo giá sản phẩm Goal Gửi tin nhắn thông báo yêu cầu nhận báo giá tới công ty Actors Guest, Admin Pre-conditions Post-conditions Flow of events Basic flow 41
  50. (Thành công) 1. Truy cập vào đường dẫn Website. 2. Chọn nút “Nhận Báo Giá”. 3. Hệ thống sẽ đưa ra một mẫu đơn đăng ký nhận báo giá với các thông tin yêu cầu như họ tên, số điện thoại, địa chỉ và nội dung yêu cầu. 4. Sau khi điền đầy đủ các trường yêu cầu, nhấn nút xác nhận. 5. Hệ thống chuyển yêu cầu đến trang quản trị của admin. 6. Hệ thống trả về thông báo “Đăng ký nhận báo giá thành công”. Alternativeflow (Thất bại) 1. Truy cập vào đường dẫn Website. 2. Chọn nút “Nhận Báo Giá”. 3. Hệ thống sẽ đưa ra một mẫu đơn đăng ký nhận báo giá với các thông tin yêu cầu như họ tên, số điện thoại, địa chỉ và nội dung yêu cầu. 42
  51. 4. Sau khi điền đầy đủ các trường yêu cầu, nhấn nút xác nhận. 5. Hệ thống không phản hồi hoặc không trả về bất kỳ thông báo nào. Extension Không có Use Case ID UC_6.1 Name Cập nhập thông tin Goal Thay đổi thông tin tài khoản Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow (Thành công) 1. Người dùng nhấp vào logo avatar người dùng. 2. Hệ thống sẽ hiện ra một danh sách chức năng trong đó có nút cập nhập thông tin, chọn chức năng cập nhập thông tin. 43
  52. 3. Hệ thống sẽ chuyển hướng đến trang cập nhập thông tin và hiển thị các thông tin đã được thiết lập lần trước trên trang như tên đăng nhập, tên người dùng. 4. Người dùng tùy ý thay đổi thông tin được thiết lập lần trước, sau đó nhấn nút cập nhập. 5. Hệ thống thay đổi thông tin của bản user trong Database, và sau đó xuất ra thông báo cập nhập thành công. Alternativeflow (Thất bại) 1. Người dùng nhấp vào logo avatar người dùng. 2. Hệ thống sẽ hiện ra một danh sách chức năng trong đó có nút cập nhập thông tin, chọn chức năng cập nhập thông tin. 3. Hệ thống sẽ chuyển hướng đến trang cập nhập thông tin và hiển thị các thông tin đã được thiết lập lần trước trên trang như tên đăng nhập, tên người dùng. 4. Người dùng tùy ý thay đổi thông tin được thiết lập lần trước, sau đó nhấn nút cập nhập. 5. Hệ thống không phản hồi hoặc xuất ra thông báo các trường nhập bị lỗi. 44
  53. Extension Không có Use Case ID UC_6.2 Name Thay đổi mật khẩu Goal Thay đổi thông tin mật khẩu tài khoản Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow (Thành công) 1. Người dùng nhấp vào logo avatar người dùng. 2. Hệ thống sẽ hiện ra một danh sách chức năng trong đó có nút cập nhập thông tin, chọn chức năng cập nhập thông tin. 3. Hệ thống sẽ chuyển hướng đến trang cập nhập thông tin. 4. Người dùng tích chọn vào checkbox đổi mật khẩu, sau đó hai phần mật khẩu và xác nhận mật khẩu sẽ sáng lên. 45
  54. 5. Người dùng đặt mật khẩu mới trong phần mật khẩu và nhập lại mật khẩu mới trong phần xác nhận mật khẩu, sau đó nhấn nút cập nhập. 6. Hệ thống thay đổi thông tin mật khẩu của bản user trong Database, và sau đó xuất ra thông báo cập nhập thành công. Alternativeflow (Thất bại) 1. Người dùng nhấp vào logo avatar người dùng. 2. Hệ thống sẽ hiện ra một danh sách chức năng trong đó có nút cập nhập thông tin, chọn chức năng cập nhập thông tin. 3. Hệ thống sẽ chuyển hướng đến trang cập nhập thông tin. 4. Người dùng tích chọn vào checkbox đổi mật khẩu, sau đó hai phần mật khẩu và xác nhận mật khẩu sẽ sáng lên. 5. Người dùng đặt mật khẩu mới trong phần mật khẩu và nhập lại mật khẩu mới trong phần xác nhận mật khẩu, sau đó nhấn nút cập nhập. 6. Hệ thống không phản hồi hoặc xuất ra thông báo các trường nhập bị lỗi. 46
  55. Extension Không có Use Case ID UC_7.1 Name Nhận thông báo yêu cầu mới Goal Thông báo các yêu cầu mới chưa xem từ khách hàng Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow (Thành công) 1. Biểu tượng lá thư bên cạnh logo người dùng sẽ hiện thông báo số yêu cầu từ khách hàng chưa được xem. 2. Nhấn vào biểu tượng lá thư, sau đó hệ thống sẽ hiện ra một hộp danh sách chứa các tóm tắt về những yêu cầu chưa được đọc. Alternativeflow (Thất bại) 1. Biểu tượng lá thư bên cạnh logo người dùng sẽ hiện thông báo số yêu cầu từ khách hàng chưa được xem. 47
  56. 2. Nhấn vào biểu tượng lá thư, hệ thống không hiện ra bất kỳ danh sách nào mặc dù số yêu cầu chưa đọc lớn hơn 0. Extension Không có Use Case ID UC_7.2 Name Xem danh sách các yêu cầu Goal Hiển thị tất cả danh sách yêu cầu nhận báo giá từ khách hàng Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow (Thành công) 1. Nhấn vào biểu tượng lá thư bên cạnh logo người dùng, sau đó chọn mục xem tất cả ở vị trí dưới cùng. 2. Hệ thống trả về trang danh sách tất cả các yêu cầu nhận báo giá của khách hàng từ trước đến nay. Alternativeflow (Thất bại) 48
  57. 1. Nhấn vào biểu tượng lá thư bên cạnh logo người dùng, sau đó chọn mục xem tất cả ở vị trí dưới cùng. 2. Hệ thống không phản hồi hoặc trả về sai trang. Extension Không có Use Case ID UC_7.3 Name Xem chi tiết yêu cầu Goal Hiển thị chi tiết nội dung yêu cầu nhận báo giá từ khách hàng Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow (Thành công) 1. Nhấn vào biểu tượng lá thư bên cạnh logo người dùng, sau đó chọn mục xem tất cả ở vị trí dưới cùng. 2. Hệ thống trả về trang chứa danh sách tất cả các yêu cầu nhận báo giá của khách hàng. 3. Chọn một yêu cầu bất kỳ trong danh sách. 49
  58. 4. Hệ thống trả về trang nội dung chi tiết của yêu cầu đó. Alternativeflow (Thất bại) 1. Nhấn vào biểu tượng lá thư bên cạnh logo người dùng, sau đó chọn mục xem tất cả ở vị trí dưới cùng. 2. Hệ thống trả về trang chứa danh sách tất cả các yêu cầu nhận báo giá của khách hàng. 3. Chọn một yêu cầu bất kỳ trong danh sách. 4. Hệ thống không phản hồi hoặc trả về sai trang. Extension Không có Use Case ID UC_8.1 Name Xem danh sách tin đăng Goal Hiển thị danh sách các bài đăng tương ứng với mục bài đăng được chọn. Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow 50
  59. (Thành công) 1. Chọn mục bài đăng bất kỳ. 2. Hệ thống sẽ hiện ra danh sách chức năng trong đó có chức năng xem danh sách, chọn chức năng xem danh sách. 3. Sau khi đã chọn, hệ thống lập tức điều hướng đến trang danh sách tin đăng tương ứng với mục tin đăng được chọn trước đó. Alternativeflow (Thất bại) 1. Chọn mục bài đăng bất kỳ. 2. Hệ thống sẽ hiện ra danh sách chức năng trong đó có chức năng xem danh sách, chọn chức năng xem danh sách. 3. Sau khi đã chọn, hệ thống không phản hồi hoặc chuyển hướng sai trang. Extension Không có Use Case ID UC_8.2 Name Thêm tin đăng 51
  60. Goal Thêm tin đăng mới tương ứng với mục tin đăng được chọn lên website Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow (Thành công) 1. Chọn mục bài đăng bất kỳ. 2. Hệ thống sẽ hiện ra danh sách chức năng trong đó có chức năng thêm tin đăng, chọn chức năng thêm tin đăng. 3. Sau khi đã chọn, hệ thống lập tức điều hướng đến trang thêm tin đăng tương ứng với mục tin đăng được chọn trước đó. 4. Tại trang thêm tin đăng, người dùng phải nhập các thông tin bắt buộc vào các trường của tin đăng như là tên tin, tóm tắt, hình ảnh, nội dung, 5. Sau khi đã nhập thông tin đầy đủ, nhấn nút thêm. 6. Hệ thống sẽ thêm tin đăng mới vào Database và in tin đăng đó lên website ở mục tin tương ứng với tin đăng. 52
  61. 7. Xuất ra thông báo thêm thành công ở trang thêm tin đăng. Alternativeflow (Thất bại) 1. Chọn mục bài đăng bất kỳ. 2. Hệ thống sẽ hiện ra danh sách chức năng trong đó có chức năng thêm tin đăng, chọn chức năng thêm tin đăng. 3. Sau khi đã chọn, hệ thống lập tức điều hướng đến trang thêm tin đăng tương ứng với mục tin đăng được chọn trước đó. 4. Tại trang thêm tin đăng, người dùng phải nhập các thông tin bắt buộc vào các trường của tin đăng như là tên tin, tóm tắt, hình ảnh, nội dung, 5. Sau khi đã nhập thông tin đầy đủ, nhấn nút thêm. 6. Hệ thống không phản hồi hoặc xuất hiện thông báo trường nhập bị lỗi hoặc xuất hiện thông báo thành công nhưng trên website vẫn chưa in tin mới đăng. Extension Không có Use Case ID UC_8.3 53
  62. Name Sửa tin đăng Goal Sửa tin đăng tương ứng với mục tin đăng được chọn trên website Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow (Thành công) 1. Chọn mục bài đăng bất kỳ. 2. Hệ thống sẽ hiện ra danh sách chức năng trong đó có chức năng xem danh sách, chọn chức năng xem danh sách. 3. Sau khi đã chọn, hệ thống lập tức điều hướng đến trang danh sách tin đăng tương ứng với mục tin đăng được chọn trước đó. 4. Tại trang danh sách tin đăng, tại một tin đăng bất kỳ trong danh sách, chọn chức năng sửa. 5. Hệ thống điều hướng đến trang sửa tin đăng và hiển thị các thông tin về tin đăng được thiết lập trước đó như tên tin, tóm tắt, hình ảnh, nội dung, 54
  63. 6. Người dùng tùy ý thay đổi nội dung các trường trong trang sửa tin đăng. Sau đó nhấn nút sửa. 7. Hệ thống sẽ sửa tin đăng được chọn trong Database và cập nhập lại tin đăng đó trên website. 8. Xuất ra thông báo sửa thành công ở trang sửa tin đăng. Alternativeflow (Thất bại) 1. Chọn mục bài đăng bất kỳ. 2. Hệ thống sẽ hiện ra danh sách chức năng trong đó có chức năng xem danh sách, chọn chức năng xem danh sách. 3. Sau khi đã chọn, hệ thống lập tức điều hướng đến trang danh sách tin đăng tương ứng với mục tin đăng được chọn trước đó. 4. Tại trang danh sách tin đăng, tại một tin đăng bất kỳ trong danh sách, chọn chức năng sửa. 5. Hệ thống điều hướng đến trang sửa tin đăng và hiển thị các thông tin về tin đăng được thiết lập trước đó như tên tin, tóm tắt, hình ảnh, nội dung, 55
  64. 6. Người dùng tùy ý thay đổi nội dung các trường trong trang sửa tin đăng. Sau đó nhấn nút sửa. 7. Hệ thống không phản hồi hoặc xuất hiện thông báo trường nhập bị lỗi hoặc xuất hiện thông báo thành công nhưng trên website tin đăng vẫn chưa được cập nhập. Extension Không có Use Case ID UC_8.4 Name Xóa tin đăng Goal Xóa tin đăng tương ứng với mục tin đăng được chọn trên website Actors Admin Pre-conditions Đã đăng nhập thành công (UC_1.1) và chưa đăng xuất sau đó Post-conditions Flow of events Basic flow (Thành công) 1. Chọn mục bài đăng bất kỳ. 2. Hệ thống sẽ hiện ra danh sách chức năng trong đó có chức năng xem danh sách, chọn chức năng xem danh sách. 56
  65. 3. Sau khi đã chọn, hệ thống lập tức điều hướng đến trang danh sách tin đăng tương ứng với mục tin đăng được chọn trước đó. 4. Tại trang danh sách tin đăng, tại một tin đăng bất kỳ trong danh sách, chọn chức năng xóa. 5. Hệ thống xóa tin đăng đó khỏi Database và cập nhập lại trên website. 6. Xuất ra thông báo xóa thành công ở trang danh sách tin đăng. Alternativeflow (Thất bại) 1. Chọn mục bài đăng bất kỳ. 2. Hệ thống sẽ hiện ra danh sách chức năng trong đó có chức năng xem danh sách, chọn chức năng xem danh sách. 3. Sau khi đã chọn, hệ thống lập tức điều hướng đến trang danh sách tin đăng tương ứng với mục tin đăng được chọn trước đó. 4. Tại trang danh sách tin đăng, tại một tin đăng bất kỳ trong danh sách, chọn chức năng xóa. 57
  66. 5. Hệ thống không phản hồi hoặc xuất hiện thông báo thành công nhưng trên website tin đăng vẫn chưa được xóa. Extension Không có 58
  67. CHƯƠNG 5: THIẾT KẾ WEBSITE 5.1 Thiết kế cơ sở dữ liệu 5.1.1 Lược đồ cơ sở dữ liệu Lượt đồ cơ sở dữ liệu 5.1.2 Chi tiết các trường Bảng Table tai_khoans Tên trường Kiểu dữ liệu Mô tả id Int Xác định từng bản ghi riêng 59
  68. tendn VarChar Tên đăng nhập tài khoản tenuser VarChar Tên hiển thị người dùng password VarChar Mật khẩu của người dùng, được mã hóa created_at TimeStamp Thời gian tài khoản được tạo updated_at TimeStamp Thời gian tài khoản được sửa đổi Bảng Table infoct Tên trường Kiểu dữ liệu Mô tả ID Int Xác định từng bản ghi riêng TenCT Text Tên công ty DiaChi Text Địa chỉ của công ty SDT VarChar Số điện thoại liên hệ công ty FB VarChar Facebook liên hệ công ty Email VarChar Email liên hệ công ty HinhAnh VarChar Hình ảnh về công ty GioiThieu MediumText Bài đăng giới thiệu về công ty Bảng Table thanhpham Tên trường Kiểu dữ liệu Mô tả ID Int Xác định từng bản ghi riêng TenTP Text Tên thành phẩm đã hoàn thiện DiaChi Text Địa chỉ của khách hàng TomTat Text Tóm tắt về bài đăng thành phẩm NoiDung MediumText Nội dung bài đăng thành phẩm TenKH Text Tên khách hàng 60
  69. NhanXet Text Nhận xét của khách hàng về thành phẩm AnhKH VarChar Ảnh khách hàng AnhTP VarChar Ảnh thành phẩm Bảng Table baogia Tên trường Kiểu dữ liệu Mô tả ID Int Xác định từng bản ghi riêng HoTen Text Họ tên khách hàng yêu cầu nhận báo giá DiaChi Text Địa chỉ khách hàng yêu cầu nhận báo giá SDT VarChar Số điện thoại khách hàng yêu cầu nhận báo giá GhiChu Text Nội dung yêu cầu của khách hàng DaXem Int Đánh dấu tin yêu cầu đã đọc hay chưa created_at TimeStamp Thời gian yêu cầu được tạo updated_at TimeStamp Thời gian yêu cầu được sửa đổi Bảng Table sanpham Tên trường Kiểu dữ liệu Mô tả ID Int Xác định từng bản ghi riêng TenSP Text Tên sản phẩm công ty cung cấp TomTat Text Tóm tắt về bài đăng MoTa MediumText Nội dung bài đăng NhaSX Text Nhà sản xuất ra sản phẩm mà công ty cung cấp AnhTD Varchar Ảnh đại diện sản phẩm NoiBat Int Đánh dấu sản phẩm có nổi bật hay không 61
  70. Bảng Table loaisanpham Tên trường Kiểu dữ liệu Mô tả ID Int Xác định từng bản ghi riêng TenLoai Text Tên loại sản phẩm công ty cung cấp MoTa Text Mô tả về loại sản phẩm HinhAnh VarChar Hình ảnh loại sản phẩm Bảng Table loaisanpham_sanpham Tên trường Kiểu dữ liệu Mô tả ID Int Xác định từng bản ghi riêng sanpham_id Int ID sản phẩm liên kết với ID của bản sanpham loaisanpham_id Int ID loại sản phẩm liên kết với ID của bản loaisanpham Bảng Table hinhsanpham Tên trường Kiểu dữ liệu Mô tả ID Int Xác định từng bản ghi riêng IDSanPham Int ID sản phẩm liên kết với ID của bản sanpham HinhAnh Varchar Hình ảnh của sản phẩm Bảng Table nhanxet Tên trường Kiểu dữ liệu Mô tả ID Int Xác định từng bản ghi riêng 62
  71. IDSanPham Int ID sản phẩm liên kết với ID của bản sanpham HoTen Text Họ tên người đăng nhận xét NoiDung Text Nội dung nhận xét created_at TimeStamp Thời gian nhận xét được tạo updated_at TimeStamp Thời gian nhận xét được sửa 63
  72. 5.2 Mối quan hệ giữa các bản dữ liệu Các bản dữ liệu có mối quan hệ với nhau 5.3 Thiết kế giao diện Website – Front-End − Danh sách các trang: + Trang chủ. Trang chủ website Viko 64
  73. Mục giới thiệu trên trang chủ Mục sản phẩm trên trang chủ 65
  74. Mục sản phẩm nổi bật trên trang chủ Mục tiêu chí hoạt động trên trang chủ 66
  75. Mục dự án đã thực hiên trên trang chủ Mục khách hàng nói về chúng tôi trên trang chủ 67
  76. Mục liên hệ trên trang chủ + Trang danh sách sản phẩm. Trang danh sách sản phẩm 68
  77. Mục lọc sản phẩm trên trang danh sách sản phẩm + Trang chi tiết sản phẩm. Trang chi tiết sản phẩm 69
  78. Mục bài viết trên trang chi tiết sản phẩm Mục bài viết trên trang chi tiết sản phẩm 70
  79. Mục nhận xét cùng mục sản phẩm cùng loại trên trang chi tiết sản phẩm + Trang danh sách dự án thực hiện. Trang danh sách dự án đã thưc hiện 71
  80. Mục các danh sách dự án đã thực hiện trên trang dự án đã thực hiện + Trang chi tiết dự án. Trang chi tiết dự án 72
  81. Mục bài viết trên trang chi tiết dự án Mục các dự án khác trên trang chi tiết dự án + Trang đăng nhập Admin. Trang đăng nhập Admin 73
  82. + Trang Admin. Trang Admin + Trang thêm loại sản phẩm (Admin). Trang thêm loại sản phẩm 74
  83. + Trang danh sách loại sản phẩm (Admin). Trang danh sách loại sản phẩm + Trang sửa loại sản phẩm(Admin). Trang sửa loại sản phẩm 75
  84. + Trang thêm sản phẩm (Admin). Trang thêm sản phẩm 76
  85. + Trang danh sách sản phẩm (Admin). Trang danh sách sản phẩm 77
  86. + Trang sửa sản phẩm (Admin). Trang sửa sản phẩm 78
  87. + Trang cập nhập hình ảnh sản phẩm liên quan (Admin). Trang cập nhập hình ảnh sản phẩm liên quan 79
  88. + Trang thêm dự án đã thực thiện (Admin). Trang thêm dự án đã thực hiện 80
  89. + Trang danh sách dự án đã thực thiện (Admin). Trang danh sách dự án đã thực hiện 81
  90. + Trang sửa dự án đã thực thiện (Admin). Trang sửa dự án đã thực hiện 82
  91. + Trang cập nhập thông tin công ty (Admin). Trang cập nhật thông tin công ty 83
  92. + Trang danh sách yêu cầu báo giá sản phẩm (Admin). Trang danh sách yêu cầu báo giá + Trang sửa thông tin tài khoản (Admin). Trang sửa thông tin tài khoản + Trang báo lỗi Not Found. Trang báo lỗi Not Found khi không tìm thấy trang 84
  93. 5.4 Lập trình Website – Back-End với Laravel − Tạo các Route định hướng request cho trang người dùng: − Route::get('/home','HomeController@getHome') ->name('home'); − Route::post('/tim-kiem', 'HomeController@postSearchAjax')- >name('timkiem'); − Route::post('/nhan-bao-gia', 'HomeController@postBaoGia')- >name('baogia'); − Route::get('/du-an','ShowDuAnController@getDuAn') - >name('duan'); − Route::get('/du-an/chi- tiet/{id}','ShowDuAnController@getChiTiet') - > name('chitietduan'); − Route::get('/san- pham/{id?}','ShowSanPhamController@getDanhSach') - >name('sanpham'); − Route::get('/san-pham/chi- tiet/{id}','ShowSanPhamController@getChiTiet') - >name('chitietsanpham'); − Route::post('/san-pham/chi-tiet/them-nhan- xet/{id}','ShowSanPhamController@postNhanXet') - >name('nhanxet'); − Tạo các Route định hướng request kết hợp cùng Middleware để kiểm tra đăng nhập cho trang admin: − Route::get('/admin/dang-nhap','UserController@getDangNhap'); − Route::post('/admin/dang-nhap','UserController@postDangNhap')- >name('postdangnhap'); 85
  94. − Route::get('/admin/dang-xuat','UserController@getDangXuat')- >name('getdangxuat'); − Route::group(['prefix'=>'admin','middleware'=>'AdminLogin'],funct ion () { − Route::group(['prefix'=>'loai-san-pham'],function () { − Route::get('/danh-sach','TheLoaiController@getDanhSach') - >name('dsloaisp'); − Route::get('/them','TheLoaiController@getThem') - >name('getthemloaisp'); − Route::post('/them','TheLoaiController@postThem') - >name('postthemloaisp'); − Route::get('/sua/{id}','TheLoaiController@getSua') - >name('getsualoaisp'); − Route::post('/sua/{id}','TheLoaiController@postSua') - >name('postsualoaisp'); − Route::get('/xoa/{id}','TheLoaiController@postXoa') - >name('postxoaloaisp'); − }); − Route::group(['prefix'=>'du-an-da-thuc-hien'],function () { − Route::get('/danh-sach','DuAnController@getDanhSach') - >name('dsduan'); − Route::get('/them','DuAnController@getThem') - >name('getthemduan'); − Route::post('/them','DuAnController@postThem') - >name('postthemduan'); 86
  95. − Route::get('/sua/{id}','DuAnController@getSua') - >name('getsuaduan'); − Route::post('/sua/{id}','DuAnController@postSua') - >name('postsuaduan'); − Route::get('/xoa/{id}','DuAnController@postXoa') - >name('postxoaduan'); − Route::get('/noi-dung/{id}','DuAnController@getNoiDung') - >name('getndduan'); − }); − Route::group(['prefix'=>'thong-tin-cong-ty'],function () { − Route::get('/sua/{id}','InfoCtController@getSua') - >name('getsuainfoct'); − Route::post('/sua/{id}','InfoCtController@postSua') - >name('postsuainfoct'); − }); − Route::group(['prefix'=>'san-pham'],function () { − Route::get('/danh-sach','SanPhamController@getDanhSach') - >name('dssanpham'); − Route::get('/them','SanPhamController@getThem') - >name('getthemsanpham'); − Route::post('/them','SanPhamController@postThem') - >name('postthemsanpham'); − Route::get('/sua/{id}','SanPhamController@getSua') - >name('getsuasanpham'); − Route::post('/sua/{id}','SanPhamController@postSua') - >name('postsuasanpham'); 87
  96. − Route::get('/xoa/{id}','SanPhamController@postXoa') - >name('postxoasanpham'); − Route::get('/xoacmt/{id}','SanPhamController@postXoaCmt') - >name('postxoacmt'); − Route::get('/noi- dung/{id}','SanPhamController@getNoiDung') - >name('getndsanpham'); − Route::get('/tom-tat/{id}','SanPhamController@getTomTat') - >name('getttsanpham'); − Route::get('/hinh- anh/{id}','SanPhamController@getHinhAnh') - >name('gethasanpham'); − Route::post('/hinh- anh/{id}','SanPhamController@postHinhAnh') - >name('posthasanpham'); − }); − Route::group(['prefix'=>'user'],function () { − Route::get('/sua/{id}','UserController@getSua') - >name('getsuauser'); − Route::post('/sua/{id}','UserController@postSua') - >name('postsuauser'); − }); − Route::group(['prefix'=>'bao-gia'],function () { − Route::get('/danh-sach','BaoGiaController@getDanhSach') - >name('dsbaogia'); 88
  97. − Route::get('/xoa/{id}','BaoGiaController@postXoa') - >name('postxoabaogia'); − Route::get('/chi-tiet/{id}','BaoGiaController@getChiTiet') - >name('getchitietbaogia'); − }); − }); − Tạo Middleware AdminLogin để xác nhận đăng nhập: − <?php − − namespace App\Http\Middleware; − − use Closure; − use Illuminate\Support\Facades\Auth; − class AdminLogin − { − / − * Handle an incoming request. − * − * @param \Illuminate\Http\Request $request − * @param \Closure $next − * @return mixed − */ − public function handle($request, Closure $next) − { − if(Auth::check()){ 89
  98. − return $next($request); − } − else{ − return redirect("admin/dang-nhap"); − } − } − } − Tạo các Eloquent ORM tương ứng với từng bảng trong Database, thông qua đó mỗi bảng trong Database sẽ là một Model giúp cho việc thao tác với Database một cách dễ dàng: + Bảng baogia: + <?php + + namespace App; + + use Illuminate\Database\Eloquent\Model; + + class baogia extends Model + { + // + protected $table = 'baogia'; + public $primaryKey = 'ID'; + } + 90
  99. + Bảng thanhpham: + <?php + + namespace App; + + use Illuminate\Database\Eloquent\Model; + + class thanhpham extends Model + { + // + protected $table = 'thanhpham'; + public $timestamps = false; + public $primaryKey = 'ID'; + } + + Bảng infoct: + <?php + + namespace App; + + use Illuminate\Database\Eloquent\Model; + + class infoct extends Model + { + // 91
  100. + protected $table = 'infoct'; + public $timestamps = false; + public $primaryKey = 'ID'; + } + Bảng tai_khoans: + <?php + + namespace App; + + use Illuminate\Notifications\Notifiable; + use Illuminate\Contracts\Auth\MustVerifyEmail; + use Illuminate\Foundation\Auth\User as Authenticatable; + + class tai_khoan extends Authenticatable + { + // + use Notifiable; + + / + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = [ + 'tendn','tenuser', 'password', + ]; 92
  101. + + / + * The attributes that should be hidden for arrays. + * + * @var array + */ + protected $hidden = [ + 'password', 'remember_token', + ]; + } + + Bảng sanpham: + <?php + + namespace App; + + use Illuminate\Database\Eloquent\Model; + + class sanpham extends Model + { + // + protected $table = 'sanpham'; + public $timestamps = false; + public $primaryKey = 'ID'; + public function loaisanpham(){ 93
  102. + return $this- >belongsToMany('App\loaisanpham','loaisanpham_sanpham','sa npham_id','loaisanpham_id'); + } + + public function hinhsanpham(){ + return $this- >hasMany('App\hinhsanpham','IDSanPham','ID'); + } + + public function nhanxet(){ + return $this -> hasMany('App\nhanxet','IDSanPham','ID'); + } + } + + Bảng loaisanpham: + <?php + + namespace App; + + use Illuminate\Database\Eloquent\Model; + + class loaisanpham extends Model + { + // 94
  103. + protected $table = 'loaisanpham'; + public $timestamps = false; + public $primaryKey = 'ID'; + + public function sanpham(){ + return $this- >belongsToMany('App\sanpham','loaisanpham_sanpham','loaisa npham_id','sanpham_id'); + } + } + + Bảng nhanxet: + belongsTo('App\sanpham','IDSanPham','ID'); 95
  104. + } + } + + Bảng hinhsanpham: + belongsTo('App\sanpham','IDSanPham','ID'); + } + } − Tạo các Controller để xử lý, điều hướng giữa Model và View sau khi nhận request thông qua Route từ trình duyệt: 96
  105. + BaoGiaController: + $ baogias]); + } + public function postXoa(Request $request){ + $query = $request ->id; + $baogia = baogia::find($query); + if(isset($baogia)){ + $baogia ->delete(); + return redirect('admin/bao-gia/danh-sach') - >with('thongbao','Xóa thành công'); + } + else{ + return view('admin.erorr.notfound'); 97
  106. + } + } + public function getChiTiet(Request $request){ + $query = $request ->id; + $ctbaogia = baogia::find($query); + if(isset($ctbaogia)){ + $ctbaogia ->DaXem=1; + $ctbaogia ->save(); + return view('admin.baogia.chitietbaogia',['ctbaogia'=>$ctbao gia]); + } + else{ + return view('admin.erorr.notfound'); + } + } + } + DuAnController: + <?php + + namespace App\Http\Controllers; + + use Illuminate\Http\Request; + use App\thanhpham; + use SebastianBergmann\Environment\Console; + 98
  107. + class DuAnController extends Controller + { + // + public function getDanhSach(){ + $thanhpham = thanhpham::all(); + return view('admin.thanhpham.danhsachduan',['thanhphams' => $thanhpham]); + } + public function getThem(){ + return view('admin.thanhpham.themduan'); + } + public function postThem(Request $request){ + if($request ->hasFile('file')){ + $hinhanh = $request ->file('file'); + $name = $hinhanh ->getClientOriginalName(); + $destinationPath = 'img/'; + if (!file_exists($destinationPath)) { + mkdir($destinationPath, 0755, true); + } + $hinhanh->move($destinationPath, $name); + } + else if($request ->input('anhtieude')!="" && $request - >input('anhkh')!="" && $request - >input('noidung')!="" && $request ->input('nhanxet')!=""){ + $this -> validate($request,[ + 'tenduan' =>'required|min:2|max:50', 99
  108. + 'diachi' =>'required|min:2|max:100', + 'tenkh' =>'required|min:2|max:50', + 'nhanxet' =>'required|min:2', + 'noidung' =>'required|min:2', + 'tomtat' =>'required|min:2|max:300', + ], + [ + 'tenduan.required'=>'Bạn chưa nhập tên dự án', + 'tenduan.min'=>'Tên dự án phải có độ dài lớn hơn 1 ký tự', + 'tenduan.max'=>'Tên dự án phải có độ dài nhỏ hơn 50 ký tự', + 'diachi.required'=>'Bạn chưa nhập địa chỉ', + 'diachi.min'=>'Địa chỉ phải có độ dài lớn hơn 1 ký tự', + 'diachi.max'=>'Địa chỉ phải có độ dài nhỏ hơn 100 ký t ự', + 'tenkh.required'=>'Bạn chưa nhập tên khách hàng', + 'tenkh.min'=>'Tên khách hàng phải có độ dài lớn hơn 1 ký tự', + 'tenkh.max'=>'Tên khách hàng có độ dài nhỏ hơn 50 ký tự', + 'nhanxet.required'=>'Bạn chưa nhập nhận xét', + 'nhanxet.min'=>'Nhận xét phải có độ dài lớn hơn 1 ký t ự', + 'noidung.required'=>'Bạn chưa nhập nội dung', 100
  109. + 'noidung.min'=>'Nội dung phải có độ dài lớn hơn 1 ký tự', + 'tomtat.required'=>'Bạn chưa nhập tóm tắt', + 'tomtat.min'=>'Tóm tắt phải có độ dài lớn hơn 1 ký tự', + 'tomtat.max'=>'Tóm tắt phải có độ dài nhỏ hơn 300 ký tự', + ]); + $thanhpham = new thanhpham; + $thanhpham -> TenTP = $request -> tenduan; + $thanhpham -> DiaChi = $request -> diachi; + $thanhpham -> NoiDung = $request -> noidung; + $thanhpham -> TenKH = $request -> tenkh; + $thanhpham -> NhanXet = $request -> nhanxet; + $thanhpham -> TomTat =$request -> tomtat; + $thanhpham -> AnhKH = $request -> anhkh; + $thanhpham -> AnhTP = $request -> anhtieude; + $thanhpham ->save(); + return redirect('/admin/du-an-da-thuc-hien/them') - > with('thongbao','Thêm thành công'); + + } + else{ + return redirect('/admin/du-an-da-thuc-hien/them')- > with('err','Bạn cần thêm đầy đủ các trường bắt buộc'); + } + } 101
  110. + public function postXoa(Request $request){ + $query = $request ->id; + $thanhpham = thanhpham::find($query); + if(isset($thanhpham)){ + $image_path1 = "img/".$thanhpham -> AnhKH; + $image_path2 = "img/".$thanhpham -> AnhTP; + + if (file_exists($image_path1)) { + + @unlink($image_path1); + } + if (file_exists($image_path2)) { + + @unlink($image_path2); + } + $thanhpham ->delete(); + return redirect('/admin/du-an-da-thuc-hien/danh-sach') - >with('thongbao','Xóa thành công'); + } + else{ + return view('admin.erorr.notfound'); + } + } + public function getSua(Request $request){ + $query = $request ->id; + $thanhpham = thanhpham::find($query); 102
  111. + if(isset($thanhpham)){ + return view('admin.thanhpham.suaduan',['thanhpham'=>$tha nhpham]); + } + else{ + return view('admin.erorr.notfound'); + } + } + public function postSua(Request $request){ + $query = $request ->id; + $thanhpham = thanhpham::find($query); + if($request ->hasFile('file')){ + $hinhanh = $request ->file('file'); + $name = $hinhanh ->getClientOriginalName(); + $destinationPath = 'img/'; + if (!file_exists($destinationPath)) { + mkdir($destinationPath, 0755, true); + } + $hinhanh->move($destinationPath, $name); + } + else if($request ->input('tenduan')!="" && $request - >input('diachi')!=""&& $request - >input('tenkh')!="" && $request - >input('nhanxet')!="" && $request ->input('noidung')!=""){ + $this -> validate($request,[ + 'tenduan' =>'required|min:2|max:50', 103
  112. + 'diachi' =>'required|min:2|max:100', + 'tenkh' =>'required|min:2|max:50', + 'nhanxet' =>'required|min:2', + 'noidung' =>'required|min:9', + 'tomtat' =>'required|min:2|max:300', + ], + [ + 'tenduan.required'=>'Bạn chưa nhập tên dự án', + 'tenduan.min'=>'Tên dự án phải có độ dài lớn hơn 1 ký tự', + 'tenduan.max'=>'Tên dự án phải có độ dài nhỏ hơn 50 ký tự', + 'diachi.required'=>'Bạn chưa nhập địa chỉ', + 'diachi.min'=>'Địa chỉ phải có độ dài lớn hơn 1 ký tự', + 'diachi.max'=>'Địa chỉ phải có độ dài nhỏ hơn 100 ký t ự', + 'tenkh.required'=>'Bạn chưa nhập tên khách hàng', + 'tenkh.min'=>'Tên khách hàng phải có độ dài lớn hơn 1 ký tự', + 'tenkh.max'=>'Tên khách hàng có độ dài nhỏ hơn 50 ký tự', + 'nhanxet.required'=>'Bạn chưa nhập nhận xét', + 'nhanxet.min'=>'Nhận xét phải có độ dài lớn hơn 1 ký t ự', + 'noidung.required'=>'Bạn chưa nhập nội dung', 104
  113. + 'noidung.min'=>'Nội dung phải có độ dài lớn hơn 1 ký tự', + 'tomtat.required'=>'Bạn chưa nhập tóm tắt', + 'tomtat.min'=>'Tóm tắt phải có độ dài lớn hơn 1 ký tự', + 'tomtat.max'=>'Tóm tắt phải có độ dài nhỏ hơn 300 ký tự', + ]); + $thanhpham -> TenTP = $request -> tenduan; + $thanhpham -> DiaChi = $request -> diachi; + $thanhpham -> TenKH = $request -> tenkh; + $thanhpham -> NhanXet = $request -> nhanxet; + $thanhpham -> TomTat =$request -> tomtat; + $thanhpham -> NoiDung = $request -> noidung; + if($request -> anhtieude !="" && $request - > anhtieude != $thanhpham -> AnhTP){ + $image_path = "img/".$thanhpham -> AnhTP; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $thanhpham -> AnhTP =$request -> anhtieude; + } + if($request -> anhkh !="" && $request - > anhkh != $thanhpham -> AnhKH){ + $image_path = "img/".$thanhpham -> AnhKH; 105
  114. + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $thanhpham -> AnhKH =$request -> anhkh; + } + $thanhpham ->save(); + return view('admin.thanhpham.suaduan',['thanhpham'=>$ thanhpham]) -> with('thongbao','Sửa thành công'); + + } + else{ + return view('admin.thanhpham.suaduan',['thanhpham'=>$ thanhpham]) -> with('err','Bạn không được bỏ trống nội dung'); + } + } + public function getNoiDung(Request $request){ + $query = $request ->id; + $thanhpham = thanhpham::find($query); + if(isset($thanhpham)){ + return view('admin.thanhpham.noidungduan',['thanhpham' = > $thanhpham]); + } + else{ + return view('admin.erorr.notfound'); 106
  115. + } + } + } + InfoCtController: + first(); + return view('admin.thongtinct.thongtinct',['info'=>$info]); + } + public function postSua(Request $request){ + $query = $request ->id; + $info = infoct::find($query); + if($request ->hasFile('file')){ + $hinhanh = $request ->file('file'); + $name = $hinhanh ->getClientOriginalName(); 107
  116. + $destinationPath = 'img/'; + if (!file_exists($destinationPath)) { + mkdir($destinationPath, 0755, true); + } + $hinhanh->move($destinationPath, $name); + } + else if($request ->input('tenct')!="" && $request - >input('diachi')!=""&& $request ->input('gioithieu')!="" + && $request ->input('sdt')!="" && $request - >input('fb')!="" && $request ->input('email')!=""){ + $this -> validate($request,[ + 'tenct' =>'required|min:2|max:50|', + 'diachi' =>'required|min:2|max:100|', + 'sdt' =>'required|numeric|digits_between:3,10', + 'fb' =>'required|min:2|max:100|', + 'email' =>'required|email|', + 'gioithieu' =>'required|min:2|', + ], + [ + 'tenct.required'=>'Bạn chưa nhập tên công ty', + 'tenct.min'=>'Tên công ty phải có độ dài lớn hơn 1 ký t ự', + 'tenct.max'=>'Tên công ty phải có độ dài nhỏ hơn 50 k ý tự', + 'diachi.required'=>'Bạn chưa nhập địa chỉ', + 'diachi.min'=>'Địa chỉ phải có độ dài lớn hơn 1 ký tự', 108
  117. + 'diachi.max'=>'Địa chỉ phải có độ dài nhỏ hơn 100 ký t ự', + 'sdt.required'=>'Bạn chưa nhập số điện thoại', + 'sdt.numeric'=>'Số điện thoại chỉ bao gồm số', + 'sdt.digits_between'=>'Số điện thoại phải lớn hơn 2 số và nhỏ hơn 11 số', + 'fb.required'=>'Bạn chưa nhập thông tin facebook', + 'fb.min'=>'Thông tin facebook phải có độ dài lớn hơn 1 ký tự', + 'fb.max'=>'Thông tin facebook phải có độ dài nhỏ hơn 100 ký tự', + 'email.required'=>'Bạn chưa nhập thông tin email', + 'email.email'=>'Email không hợp lệ', + 'gioithieu.required'=>'Bạn chưa nhập giới thiệu', + 'gioithieu.min'=>'Gới thiệu phải có độ dài lớn hơn 1 ký tự', + ]); + $info -> TenCT = $request -> tenct; + $info -> DiaChi = $request -> diachi; + $info -> SDT = $request -> sdt; + $info-> FB = $request -> fb; + $info -> Email = $request -> email; + $info -> GioiThieu = $request -> gioithieu; + if($request -> anhct !="" && $request -> anhct != $info - > HinhAnh){ + $image_path = "img/".$info -> HinhAnh; 109
  118. + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $info -> HinhAnh =$request -> anhct; + } + $info ->save(); + return view('admin.thongtinct.thongtinct',['info'=>$info]) -> with('thongbao','Sửa thành công'); + + } + else{ + return view('admin.thongtinct.thongtinct',['info'=>$info]) -> with('err','Bạn không được bỏ trống phần giới thiệu'); + } + } + } + + SanPhamController: + <?php + + namespace App\Http\Controllers; + + use Illuminate\Http\Request; 110
  119. + use App\sanpham; + use App\loaisanpham; + use App\hinhsanpham; + use App\nhanxet; + class SanPhamController extends Controller + { + // + public function getDanhSach() { + $sanpham = sanpham::all(); + return view('admin.sanpham.danhsachsanpham',['sanphams' => $sanpham]); + } + public function getThem(){ + $loaisanphams =loaisanpham::all(); + return view('admin.sanpham.themsanpham',['loaisanphams' => $loaisanphams]); + } + public function postThem(Request $request){ + if($request ->hasFile('file')){ + $hinhanh = $request ->file('file'); + $name = $hinhanh ->getClientOriginalName(); + $destinationPath = 'img/'; + if (!file_exists($destinationPath)) { + mkdir($destinationPath, 0755, true); + } + $hinhanh->move($destinationPath, $name); 111
  120. + } + else if($request ->input('hinhanh')!="" && $request - >input('noidung')!="" && $request ->input('tomtat')!=""){ + $this -> validate($request,[ + 'tensp' =>'required|min:2|max:50|unique:sanpham,TenS P', + 'tomtat' =>'required|min:9', + 'noidung' =>'required|min:9', + 'nhasx' =>'required|min:2|max:50', + + ], + [ + 'tensp.required'=>'Bạn chưa nhập tên sản phẩm', + 'tensp.min'=>'Tên sản phẩm phải có độ dài lớn hơn 1 k ý tự', + 'tensp.max'=>'Tên sản phẩm phải có độ dài nhỏ hơn 50 ký tự', + 'tensp.unique'=>'Tên sản phẩm đã tồn tại', + 'tomtat.required'=>'Bạn chưa nhập tóm tắt', + 'tomtat.min'=>'Phần tóm tắt phải có độ dài lớn hơn 1 k ý tự', + 'noidung.required'=>'Bạn chưa nhập nội dung', + 'noidung.min'=>'Phần nội dung phải có độ dài lớn hơn 1 ký tự', + 'nhasx.required'=>'Bạn chưa nhập tên nhà sản xuất', 112
  121. + 'nhasx.min'=>'Phần tên nhà sản xuất phải có độ dài lớn hơn 1 ký tự', + 'nhasx.max'=>'Phần tên nhà sản xuất phải có độ dài nh ỏ hơn 50 ký tự', + ]); + $sanpham = new sanpham; + $sanpham -> TenSP = $request -> tensp; + $sanpham -> TomTat = $request -> tomtat; + $sanpham -> MoTa =$request -> noidung; + $sanpham -> NhaSX =$request -> nhasx; + if ( $request->has('noibat')) { + $sanpham ->NoiBat = 1; + } + else{ + $sanpham ->NoiBat = 0; + } + $sanpham -> AnhTD = $request -> hinhanh; + $sanpham ->save(); + $pivot= sanpham::find($sanpham ->ID); + foreach($request ->loaisp as $lsp){ + $pivot ->loaisanpham()->attach($lsp); + } + return redirect('/admin/san-pham/them') - >with('thongbao','Thêm thành công'); + + } 113
  122. + else{ + return redirect('/admin/san-pham/them') - >with('err','Bạn cần nhập đầy đủ các trường bắt buộc'); + } + } + public function postXoa(Request $request){ + $query = $request ->id; + $sanpham = sanpham::find($query); + if(isset($sanpham)){ + $image_path = "img/".$sanpham -> AnhTD; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $sanpham ->delete(); + return redirect('/admin/san-pham/danh-sach') - >with('thongbao','Xóa thành công'); + } + else{ + return view('admin.erorr.notfound'); + } + } + public function postXoaCmt(Request $request){ + $query = $request ->id; + $cmt = nhanxet::find($query); 114
  123. + if(isset($cmt)){ + $idsanpham =$cmt->IDSanPham; + $cmt ->delete(); + return redirect('/admin/san-pham/sua/'.$idsanpham) - >with('thongbao','Xóa thành công'); + } + else{ + return view('admin.erorr.notfound'); + } + } + public function getSua(Request $request){ + $query = $request ->id; + $sanpham = sanpham::find($query); + if(isset($sanpham)){ + $loaisanphams =loaisanpham::all(); + $comments = $sanpham ->nhanxet()->get(); + $loaidcchons = $sanpham ->loaisanpham()- >select('TenLoai')->get(); + return view('admin.sanpham.suasanpham',['sanpham'=>$san pham,'loaisanphams'=>$loaisanphams,'loaidcchons'=>$loaidcch ons,'comments'=>$comments]); + } + else{ + return view('admin.erorr.notfound'); + } + } 115
  124. + public function postSua(Request $request){ + $query = $request ->id; + $sanpham = sanpham::find($query); + $comments = $sanpham ->nhanxet()->get(); + if($request ->hasFile('file')){ + $hinhanh = $request ->file('file'); + $name = $hinhanh ->getClientOriginalName(); + $destinationPath = 'img/'; + if (!file_exists($destinationPath)) { + mkdir($destinationPath, 0755, true); + } + $hinhanh->move($destinationPath, $name); + } + else if($request ->input('noidung')!="" &&$request - >input('tomtat')!=""){ + if($request ->input('tensp')== $sanpham -> TenSP){ + $this -> validate($request,[ + 'tensp' =>'required|min:2|max:50', + 'tomtat' =>'required|min:9', + 'noidung' =>'required|min:9', + 'nhasx' =>'required|min:2|max:50', + + ], + [ + 'tensp.required'=>'Bạn chưa nhập tên sản phẩm', 116
  125. + 'tensp.min'=>'Tên sản phẩm phải có độ dài lớn hơn 1 k ý tự', + 'tensp.max'=>'Tên sản phẩm phải có độ dài nhỏ hơn 50 ký tự', + 'tomtat.required'=>'Bạn chưa nhập tóm tắt', + 'tomtat.min'=>'Phần tóm tắt phải có độ dài lớn hơn 1 k ý tự', + 'noidung.required'=>'Bạn chưa nhập nội dung', + 'noidung.min'=>'Phần nội dung phải có độ dài lớn hơn 1 ký tự', + 'nhasx.required'=>'Bạn chưa nhập tên nhà sản xuất', + 'nhasx.min'=>'Phần tên nhà sản xuất phải có độ dài lớn hơn 1 ký tự', + 'nhasx.max'=>'Phần tên nhà sản xuất phải có độ dài nh ỏ hơn 50 ký tự', + ]); + }else{ + $this -> validate($request,[ + 'tensp' =>'required|min:2|max:50|unique:sanpham,Te nSP', + 'tomtat' =>'required|min:9', + 'noidung' =>'required|min:9', + 'nhasx' =>'required|min:2|max:50', + ], + [ + 'tensp.required'=>'Bạn chưa nhập tên sản phẩm', 117
  126. + 'tensp.min'=>'Tên sản phẩm phải có độ dài lớn hơn 1 ký tự', + 'tensp.max'=>'Tên sản phẩm phải có độ dài nhỏ hơn 50 ký tự', + 'tensp.unique'=>'Tên sản phẩm đã tồn tại', + 'tomtat.required'=>'Bạn chưa nhập tóm tắt', + 'tomtat.min'=>'Phần tóm tắt phải có độ dài lớn hơn 1 ký tự', + 'noidung.required'=>'Bạn chưa nhập nội dung', + 'noidung.min'=>'Phần nội dung phải có độ dài lớn h ơn 1 ký tự', + 'nhasx.required'=>'Bạn chưa nhập tên nhà sản xuất', + 'nhasx.min'=>'Phần tên nhà sản xuất phải có độ dài l ớn hơn 1 ký tự', + 'nhasx.max'=>'Phần tên nhà sản xuất phải có độ dài nhỏ hơn 50 ký tự', + ]); + } + $sanpham -> TenSP = $request -> tensp; + $sanpham -> TomTat = $request -> tomtat; + $sanpham -> MoTa =$request -> noidung; + $sanpham -> NhaSX =$request -> nhasx; + if ( $request->has('noibat')) { + $sanpham ->NoiBat = 1; + } + else{ 118
  127. + $sanpham ->NoiBat = 0; + } + if($request -> hinhanh !="" && $request - > hinhanh != $sanpham -> AnhTD){ + $image_path = "img/".$sanpham -> AnhTD; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $sanpham -> AnhTD =$request -> hinhanh; + } + $sanpham ->save(); + $pivot= sanpham::find($sanpham ->ID); + $pivot ->loaisanpham()->sync($request->loaisp); + $loaisanphams =loaisanpham::all(); + $loaidcchons = $sanpham ->loaisanpham()- >select('TenLoai')->get(); + return view('admin.sanpham.suasanpham',['sanpham'=>$s anpham,'loaisanphams'=>$loaisanphams,'loaidcchons'=>$loaidcc hons,'comments'=>$comments])- > with('thongbao','Bạn đã sửa thành công'); + + } + else{ + $loaisanphams =loaisanpham::all(); 119
  128. + $loaidcchons = $sanpham ->loaisanpham()- >select('TenLoai')->get(); + return view('admin.sanpham.suasanpham',['sanpham'=>$s anpham,'loaisanphams'=>$loaisanphams,'loaidcchons'=>$loaidcc hons,'comments'=>$comments]) - > with('err','Bạn không được bỏ trống nội dung hoặc tóm tắt'); + } + } + public function getNoiDung(Request $request){ + $query = $request ->id; + $sanpham = sanpham::find($query); + if(isset($sanpham)){ + return view('admin.sanpham.noidungsanpham',['sanpham' = > $sanpham]); + } + else{ + return view('admin.erorr.notfound'); + } + } + public function getTomTat(Request $request){ + $query = $request ->id; + $sanpham = sanpham::find($query); + if(isset($sanpham)){ + return view('admin.sanpham.tomtatsanpham',['sanpham' => $sanpham]); + } 120
  129. + else{ + return view('admin.erorr.notfound'); + } + } + public function getHinhAnh(Request $request){ + $query = $request ->id; + $sanpham = sanpham::find($query); + if(isset($sanpham)){ + $hinhanhs= $sanpham -> hinhsanpham() - >select('ID','HinhAnh')->get(); + return view('admin.sanpham.hinhanhsanpham',['sanpham' = > $sanpham,'hinhanhs' => $hinhanhs]); + } + else{ + return view('admin.erorr.notfound'); + } + } + public function postHinhAnh(Request $request){ + $query = $request ->id; + $sanpham = sanpham::find($query); + if($request ->hasFile('file')){ + $hinhanh = $request ->file('file'); + $name = $hinhanh ->getClientOriginalName(); + $destinationPath = 'img/'; + if (!file_exists($destinationPath)) { + mkdir($destinationPath, 0755, true); 121
  130. + } + $hinhanh->move($destinationPath, $name); + } + //Them + if($request ->idanh1=="" && $request - >hinhanh1 !=""&& $request ->hinhanh1 !="xoa"){ + $hinhsp = new hinhsanpham; + $hinhsp ->IDSanPham = $query; + $hinhsp ->HinhAnh =$request ->hinhanh1; + $hinhsp -> save(); + } + if($request ->idanh2=="" && $request - >hinhanh2 !=""&& $request ->hinhanh2 !="xoa"){ + $hinhsp = new hinhsanpham; + $hinhsp ->IDSanPham = $query; + $hinhsp ->HinhAnh =$request ->hinhanh2; + $hinhsp -> save(); + } + if($request ->idanh3=="" && $request - >hinhanh3 !=""&& $request ->hinhanh3 !="xoa"){ + $hinhsp = new hinhsanpham; + $hinhsp ->IDSanPham = $query; + $hinhsp ->HinhAnh =$request ->hinhanh3; + $hinhsp -> save(); + } 122
  131. + if($request ->idanh4=="" && $request - >hinhanh4 !=""&& $request ->hinhanh4 !="xoa"){ + $hinhsp = new hinhsanpham; + $hinhsp ->IDSanPham = $query; + $hinhsp ->HinhAnh =$request ->hinhanh4; + $hinhsp -> save(); + } + if($request ->idanh5=="" && $request - >hinhanh5 !=""&& $request ->hinhanh5 !="xoa"){ + $hinhsp = new hinhsanpham; + $hinhsp ->IDSanPham = $query; + $hinhsp ->HinhAnh =$request ->hinhanh5; + $hinhsp -> save(); + } + //Xoa + if($request ->idanh1!="" && $request - >hinhanh1 =="xoa"){ + $hinhsp = hinhsanpham::find($request ->idanh1); + $image_path = "img/".$hinhsp -> HinhAnh; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $hinhsp -> delete(); + } 123
  132. + if($request ->idanh2!="" && $request - >hinhanh2 =="xoa"){ + $hinhsp = hinhsanpham::find($request ->idanh2); + $image_path = "img/".$hinhsp -> HinhAnh; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $hinhsp -> delete(); + } + if($request ->idanh3!="" && $request - >hinhanh3 =="xoa"){ + $hinhsp = hinhsanpham::find($request ->idanh3); + $image_path = "img/".$hinhsp -> HinhAnh; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $hinhsp -> delete(); + } + if($request ->idanh4!="" && $request - >hinhanh4 =="xoa"){ + $hinhsp = hinhsanpham::find($request ->idanh4); + $image_path = "img/".$hinhsp -> HinhAnh; 124
  133. + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $hinhsp -> delete(); + } + if($request ->idanh5!="" && $request - >hinhanh5 =="xoa"){ + $hinhsp = hinhsanpham::find($request ->idanh5); + $image_path = "img/".$hinhsp -> HinhAnh; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $hinhsp -> delete(); + } + //Sua + if($request ->idanh1!="" && $request - >hinhanh1 !="xoa"&& $request ->hinhanh1 !=""){ + $hinhsp = hinhsanpham::find($request ->idanh1); + if($request->hinhanh1 != $hinhsp ->HinhAnh){ + $image_path = "img/".$hinhsp -> HinhAnh; + if (file_exists($image_path)) { + 125
  134. + @unlink($image_path); + } + } + $hinhsp ->HinhAnh =$request ->hinhanh1; + $hinhsp -> save(); + } + if($request ->idanh2!="" && $request - >hinhanh2 !="xoa"&& $request ->hinhanh2 !=""){ + $hinhsp = hinhsanpham::find($request ->idanh2); + if($request->hinhanh2 != $hinhsp ->HinhAnh){ + $image_path = "img/".$hinhsp -> HinhAnh; + if (file_exists($image_path)) { + + @unlink($image_path); + } + } + $hinhsp ->HinhAnh =$request ->hinhanh2; + $hinhsp -> save(); + } + if($request ->idanh3!="" && $request - >hinhanh3 !="xoa"&& $request ->hinhanh3 !=""){ + $hinhsp = hinhsanpham::find($request ->idanh3); + if($request->hinhanh3 != $hinhsp ->HinhAnh){ + $image_path = "img/".$hinhsp -> HinhAnh; + if (file_exists($image_path)) { + 126
  135. + @unlink($image_path); + } + } + $hinhsp ->HinhAnh =$request ->hinhanh3; + $hinhsp -> save(); + } + if($request ->idanh4!="" && $request - >hinhanh4 !="xoa"&& $request ->hinhanh4 !=""){ + $hinhsp = hinhsanpham::find($request ->idanh4); + if($request->hinhanh4 != $hinhsp ->HinhAnh){ + $image_path = "img/".$hinhsp -> HinhAnh; + if (file_exists($image_path)) { + + @unlink($image_path); + } + } + $hinhsp ->HinhAnh =$request ->hinhanh4; + $hinhsp -> save(); + } + if($request ->idanh5!="" && $request - >hinhanh5 !="xoa"&& $request ->hinhanh5 !=""){ + $hinhsp = hinhsanpham::find($request ->idanh5); + if($request->hinhanh5 != $hinhsp ->HinhAnh){ + $image_path = "img/".$hinhsp -> HinhAnh; + if (file_exists($image_path)) { + 127
  136. + @unlink($image_path); + } + } + $hinhsp ->HinhAnh =$request ->hinhanh5; + $hinhsp -> save(); + } + $hinhanhs= $sanpham -> hinhsanpham() - >select('ID','HinhAnh')->get(); + return view('admin.sanpham.hinhanhsanpham',['sanpham' = > $sanpham,'hinhanhs' => $hinhanhs]) - >with('thongbao','Cập nhập thành công'); + } + } + + TheLoaiController: + <?php + + namespace App\Http\Controllers; + + use Illuminate\Http\Request; + use App\loaisanpham; + use SebastianBergmann\Environment\Console; + + class TheLoaiController extends Controller + { 128
  137. + // + public function getDanhSach(){ + $loaisp = loaisanpham::all(); + return view('admin.loaisanpham.danhsachloai',['theloais' => $loaisp]); + } + public function getThem(){ + return view('admin.loaisanpham.themloai'); + } + public function postThem(Request $request){ + if($request ->hasFile('file')){ + $hinhanh = $request ->file('file'); + $name = $hinhanh ->getClientOriginalName(); + $destinationPath = 'img/'; + if (!file_exists($destinationPath)) { + mkdir($destinationPath, 0755, true); + } + $hinhanh->move($destinationPath, $name); + } + else if($request ->input('hinhanh')!=""){ + $this -> validate($request,[ + 'tenloai' =>'required|min:2|max:50|unique:loaisanpham, TenLoai', + 'mota' =>'required|min:2|max:200' + ], + [ 129
  138. + 'tenloai.required'=>'Bạn chưa nhập tên loại', + 'tenloai.min'=>'Tên loại phải có độ dài lớn hơn 1 ký tự', + 'tenloai.max'=>'Tên loại phải có độ dài nhỏ hơn 50 ký t ự', + 'tenloai.unique'=>'Tên loại đã tồn tại', + 'mota.required'=>'Bạn chưa nhập mô tả', + 'mota.min'=>'Phần mô tả phải có độ dài lớn hơn 1 ký t ự', + 'mota.max'=>'Phần mô tả phải có độ dài nhỏ hơn 200 k ý tự' + ]); + $loaisp = new loaisanpham; + $loaisp -> TenLoai = $request -> tenloai; + $loaisp -> MoTa = $request -> mota; + $loaisp -> HinhAnh =$request -> hinhanh; + $loaisp ->save(); + return redirect('/admin/loai-san-pham/them') - > with('thongbao','Thêm thành công'); + + } + else{ + return redirect('/admin/loai-san-pham/them') - > with('err','Bạn cần thêm đầy đủ các trường bắt buộc'); + } + } + public function getSua(Request $request){ 130
  139. + $query = $request ->id; + $loaisp = loaisanpham::find($query); + if(isset($loaisp)){ + return view('admin.loaisanpham.sualoai',['loaisp'=>$loaisp]) ; + } + else{ + return view('admin.erorr.notfound'); + } + } + public function postSua(Request $request){ + $query = $request ->id; + $loaisp = loaisanpham::find($query); + if($request ->hasFile('file')){ + $hinhanh = $request ->file('file'); + $name = $hinhanh ->getClientOriginalName(); + $destinationPath = 'img/'; + if (!file_exists($destinationPath)) { + mkdir($destinationPath, 0755, true); + } + $hinhanh->move($destinationPath, $name); + } + else if($request ->input('tenloai')!="" && $request - >input('mota')!=""){ + if($request ->input('tenloai')== $loaisp -> TenLoai){ + $this -> validate($request,[ 131
  140. + 'tenloai' =>'required|min:2|max:50|', + 'mota' =>'required|min:2|max:200' + ], + [ + 'tenloai.required'=>'Bạn chưa nhập tên loại', + 'tenloai.min'=>'Tên loại phải có độ dài lớn hơn 1 ký tự', + 'tenloai.max'=>'Tên loại phải có độ dài nhỏ hơn 50 ký t ự', + 'mota.required'=>'Bạn chưa nhập mô tả', + 'mota.min'=>'Phần mô tả phải có độ dài lớn hơn 1 ký t ự', + 'mota.max'=>'Phần mô tả phải có độ dài nhỏ hơn 200 k ý tự' + ]); + }else{ + $this -> validate($request,[ + 'tenloai' =>'required|min:2|max:50|unique:loaisanpha m,TenLoai', + 'mota' =>'required|min:2|max:200' + ], + [ + 'tenloai.required'=>'Bạn chưa nhập tên loại', + 'tenloai.min'=>'Tên loại phải có độ dài lớn hơn 1 ký tự', + 'tenloai.max'=>'Tên loại phải có độ dài nhỏ hơn 50 k ý tự', 132
  141. + 'tenloai.unique'=>'Tên loại đã tồn tại', + 'mota.required'=>'Bạn chưa nhập mô tả', + 'mota.min'=>'Phần mô tả phải có độ dài lớn hơn 1 ký tự', + 'mota.max'=>'Phần mô tả phải có độ dài nhỏ hơn 20 0 ký tự' + ]); + } + $loaisp -> TenLoai = $request -> tenloai; + $loaisp -> MoTa = $request -> mota; + if($request -> hinhanh !="" && $request - > hinhanh != $loaisp -> HinhAnh){ + $image_path = "img/".$loaisp -> HinhAnh; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $loaisp -> HinhAnh =$request -> hinhanh; + } + $loaisp ->save(); + return view('admin.loaisanpham.sualoai',['loaisp'=>$loais p]) -> with('thongbao','Sửa thành công'); + + } + } 133
  142. + public function postXoa(Request $request){ + $query = $request ->id; + $loaisp = loaisanpham::find($query); + if(isset($loaisp)){ + $image_path = "img/".$loaisp -> HinhAnh; + + if (file_exists($image_path)) { + + @unlink($image_path); + } + $loaisp ->delete(); + return redirect('/admin/loai-san-pham/danh-sach') - >with('thongbao','Xóa thành công'); + } + else{ + return view('admin.erorr.notfound'); + } + } + } + + UserController: + <?php + + namespace App\Http\Controllers; + 134
  143. + use Illuminate\Http\Request; + use Illuminate\Support\Facades\Auth; + use App\tai_khoan; + class UserController extends Controller + { + // + public function getSua(Request $request){ + $query = $request ->id; + $user = tai_khoan::find($query); + if(isset($user)){ + return view('admin.user.suauser',['user'=>$user]); + } + else{ + return view('admin.erorr.notfound'); + } + } + public function postSua(Request $request){ + $query = $request ->id; + $user = tai_khoan::find($query); + $this -> validate($request,[ + 'tendn' =>'required|min:4|max:12', + 'tenuser' =>'required|min:2|max:50', + + ], + [ + 'tendn.required'=>'Bạn chưa nhập tên đăng nhập', 135
  144. + 'tendn.min'=>'Tên đăng nhập phải có độ dài lớn hơn 3 ký tự', + 'tendn.max'=>'Tên đăng nhập phải có độ dài nhỏ hơn 13 k ý tự', + 'tenuser.required'=>'Bạn chưa nhập tên người dùng', + 'tenuser.min'=>'Tên người dùng phải có độ dài lớn hơn 1 ký tự', + 'tenuser.max'=>'Tên người dùng phải có độ dài nhỏ hơn 5 0 ký tự', + ]); + $user ->tendn =$request->tendn; + $user ->tenuser =$request->tenuser; + if($request->has('doimk')){ + $this -> validate($request,[ + 'mk' =>'required|min:4|max:12', + 'nhaplaimk' =>'required|same:mk', + ], + [ + 'mk.required'=>'Bạn chưa nhập mật khẩu', + 'mk.min'=>'Mật khẩu phải có độ dài lớn hơn 3 ký tự', + 'mk.max'=>'Mật khẩu phải có độ dài nhỏ hơn 13 ký tự', + 'nhaplaimk.required'=>'Bạn chưa nhập nhập lại mật kh ẩu', + 'nhaplaimk.same'=>'Nhập lại mật khẩu không khớp với mật khẩu', + ]); 136
  145. + $user ->password =bcrypt($request->mk); + } + $user ->save(); + return view('admin.user.suauser',['user'=>$user])- >with('thongbao','Cập nhập thành công'); + } + public function getDangNhap(){ + return view('admin.user.login'); + } + public function postDangNhap(Request $request){ + + $this -> validate($request,[ + 'tendn' =>'required|min:4|max:12', + 'matkhau' =>'required|min:4|max:12', + + ], + [ + 'tendn.required'=>'Bạn chưa nhập tên đăng nhập', + 'tendn.min'=>'Tên đăng nhập phải có độ dài lớn hơn 3 ký tự', + 'tendn.max'=>'Tên đăng nhập phải có độ dài nhỏ hơn 13 k ý tự', + 'matkhau.required'=>'Bạn chưa nhập mật khẩu', + 'matkhau.min'=>'Mật khẩu phải có độ dài lớn hơn 3 ký tự' , 137
  146. + 'matkhau.max'=>'Mật khẩu phải có độ dài nhỏ hơn 13 ký tự', + ]); + if(Auth::attempt(['tendn'=>$request- >tendn,'password'=>$request->matkhau])){ + return redirect("admin/loai-san-pham/danh-sach"); + }else{ + return view('admin.user.login')- >with('err','Sai tên tài khoản hoặc mật khẩu'); + }; + + } + public function getDangXuat(){ + Auth::logout(); + return view('admin.user.login'); + } + } + + HomeController: + <?php + + namespace App\Http\Controllers; + use Illuminate\Http\RedirectResponse; + use App\baogia; + use Illuminate\Http\Request; 138
  147. + use App\sanpham; + use App\infoct; + use App\loaisanpham; + use App\thanhpham; + use DB; + + class HomeController extends Controller + { + // + public function getHome(){ + $rdsanphams = sanpham::all()->toArray(); + $intro = infoct::all(); + $loaisanphams= loaisanpham::all(); + $sanphamnoibats= sanpham::where('NoiBat',1)->get(); + $thanhphams= thanhpham::all()->sortByDesc('ID'); + shuffle($rdsanphams); + return view('pages.home.home',['rdsanphams'=>$rdsanpham s,'intro'=>$intro,'loaisanphams'=>$loaisanphams,'sanphamnoibat s'=>$sanphamnoibats,'thanhphams'=>$thanhphams]); + } + public function postSearchAjax(Request $request){ + if($request->get('query')) + { + $query = $request->get('query'); + $data = DB::table('sanpham') + ->where('TenSP', 'LIKE', "%{$query}%") 139
  148. + ->get(); + $output = ' '; + foreach($data as $row) + { + $output .= ' + + '; + } + $output .= ' '; + echo $output; + } + } + public function postBaoGia(Request $request){ + $baogia = new baogia; + $baogia -> HoTen = $request->tenkh; + $baogia -> DiaChi = $request->diachi; + $baogia -> SDT =$request->sdt; + if($request->ghichu !=""){ + $baogia -> GhiChu = $request->ghichu; + } + $baogia -> save(); + return redirect('/home')- >with('thongbao', 'Đăng Ký Nhận Báo Giá Thành Công'); + } + } 140
  149. + + ShowSanPhamController: + id; + $kproducts =DB::table('loaisanpham') ->get(); + $sproducts =DB::table('sanpham') - > join('loaisanpham_sanpham','sanpham.ID','=','loaisanpham_san pham.sanpham_id') - > select('sanpham.ID','sanpham.TenSP','sanpham.AnhTD','loaisa npham_sanpham.loaisanpham_id') - >orderBy('sanpham.ID', 'desc')-> get() ->toArray() ; + for($i = 0; $i < count($sproducts); $i++){ 141
  150. + $sproducts[$i]->loaisanpham_id = 'filter-'.$sproducts[$i]- >loaisanpham_id; + } + for($i = 1; $i ID == $sproducts[$i-1]->ID){ + $sproducts[$i]->loaisanpham_id = $sproducts[$i]- >loaisanpham_id .' '. $sproducts[$i-1]->loaisanpham_id; + array_splice($sproducts,$i-1,1); + $i; + } + } + return view('pages.sanpham.danhsachsanpham')- > with(['kproducts' => $kproducts,'sproducts' => $sproducts,'sele cted' =>$selected]); + + } + public function getChiTiet(Request $request){ + $query = $request->id; + $sanpham= sanpham::find($query); + if(isset($sanpham)){ + $hinhanhs = $sanpham->hinhsanpham()->get(); + $comment = $sanpham->nhanxet()->orderBy('ID','desc')- >get(); + $cungloais = DB::table('loaisanpham_sanpham') - >select('loaisanpham_id')->where('sanpham_id',$query)->get()- >toArray(); 142
  151. + $spcungloais=array(); + foreach($cungloais as $loai){ + $loais =loaisanpham::find($loai->loaisanpham_id)- >sanpham()->get()->toArray(); + $spcungloais= array_merge($spcungloais,$loais); + } + return view('pages.sanpham.chitietsanpham',['sanpham'=>$s anpham,'nhanxet'=>$comment,'hinhanhs'=>$hinhanhs,'spcungloa is'=>$spcungloais]); + } + else{ + return view('admin.erorr.notfound'); + } + } + public function postNhanXet(Request $request){ + $query = $request->id; + $nhanxet = new nhanxet; + $nhanxet ->IDSanPham = $query; + $nhanxet ->HoTen= $request ->name; + $nhanxet ->NoiDung= $request->cmt; + $nhanxet ->save(); + return redirect("/san-pham/chi-tiet/".$query."#comment"); + } + } + 143
  152. + ShowDuAnController: + ',0)- >orderBy('ID','desc') ->paginate(6) ; + return view('pages.duan.danhsachduan',['duans'=>$duans]); + } + public function getChiTiet(Request $request){ + $query = $request->id; + $duan= thanhpham::find($query); + if(isset($duan)){ + $duans=thanhpham::all()->toArray(); + shuffle($duans); + return view('pages.duan.chitietduan',['duan'=>$duan,'duans' =>$duans]); + } + else{ 144
  153. + return view('admin.erorr.notfound'); + } + } + } + − Sử dụng Laravel Blade template để đổ và xử lý dữ liệu ngoài View: − @foreach($thanhphams as $nhanxet) − @if($loop->iteration − AnhKH) }}" class="testimonial-img" alt=""> − {{$nhanxet->TenKH}} − {{$nhanxet->DiaChi}} − − {{$nhanxet->NhanXet}} − − − @else − @break − @endif − @endforeach 5.5 Một số đoạn code nổi bật − CODE Autocomplete kết quả tìm kiếm sử dụng Ajax: 145
  154. − − $(document).ready(function(){ − $("#timkiem").keyup(function(){ − var query = $(this).val(); − if(query !=""){ − var _token = $('input[name="_token"]').val(); − $.ajax({ − url:"{{ route('timkiem') }}", − method:"POST", − data:{query:query, _token:_token}, − success:function(data){ − $('#kq').fadeIn(); − $('#kq').html(data); − } − }); − } − }); − $(document).on('click', function(){ − $('#timkiem').val(""); − $('#kq').fadeOut(); − }); − − CODE load dữ liệu cho bộ lọc: − $selected = $request->id; − $kproducts =DB::table('loaisanpham') ->get(); 146
  155. − $sproducts =DB::table('sanpham') - > join('loaisanpham_sanpham','sanpham.ID','=','loaisanpham_sanpham. sanpham_id') - > select('sanpham.ID','sanpham.TenSP','sanpham.AnhTD','loaisanpham _sanpham.loaisanpham_id') ->orderBy('sanpham.ID', 'desc')-> get() - >toArray() ; − for($i = 0; $i loaisanpham_id = 'filter-'.$sproducts[$i]- >loaisanpham_id; − } − for($i = 1; $i ID == $sproducts[$i-1]->ID){ − $sproducts[$i]->loaisanpham_id = $sproducts[$i]- >loaisanpham_id .' '. $sproducts[$i-1]->loaisanpham_id; − array_splice($sproducts,$i-1,1); − $i; − } − } − CODE phân trang danh sách dự án: − public function getDuAn(){ − $duans = thanhpham::where('ID','>',0)->orderBy('ID','desc') - >paginate(6) ; − return view('pages.duan.danhsachduan',['duans'=>$duans]); − } 147
  156. − CODE xác thực đăng nhập: − − if(Auth::attempt(['tendn'=>$request->tendn,'password'=>$request- >matkhau])){ − return redirect("admin/loai-san-pham/danh-sach"); − }else{ − return view('admin.user.login')- >with('err','Sai tên tài khoản hoặc mật khẩu'); − }; − − CODE xử lý dữ liệu từ Ajax gọi đến trong chức năng tìm kiếm: − if($request->get('query')) − { − $query = $request->get('query'); − $data = DB::table('sanpham') − ->where('TenSP', 'LIKE', "%{$query}%") − ->get(); − $output = ' '; − foreach($data as $row) − { − $output .= ' − − '; − } 148