Module này sử dụng thành phần <mailsettings> nằm trong <system.net> của tệp web.config . Để cấu hình cho module ta phải xem các thành phần cấu hình của
<system.net> /<mailsettings>/<smtp> ở bảng sau
Tiếp đến là cấu hình <system.net>/<mailSettings>/<smtp>/<network>
Cuối cùng ta sẽ tạo thêm phần cấu hình cho module . Phần này thiết lập địa chỉ thư điện tử được sử dụng để gửi thư
4.6. Model
Với module này ta sẽ chỉ cần model là lớp thực thể LINQ-to-SQL dưới đây:
Thuộc tính SMTP Mô tả
DeliveryMethod Thiết lập thuộc tính này với “network” chỉ ra cho ứng dụng
biết rằng có một mảy chủ thư điện tử bên ngoài sẽ được sử
dụng để gửi thư điện tử. Để gửi được thư thì thành phần của
<network> cần được sử dụng gồm có Nơi chứa - Host,Cổng
- Port,Tên người dùng - UserName,Mật khẩu- Password, và Chứng thực mặc định - DefaultCredentials.
From Chỉ ra địa chỉ email sẽ được đặt trong mục “From” khi ứng
dụng gửi thư đi
ConfigSource Định nghĩa một nguồn ngoài cho các thiết lập cấu hình thư ví
dụ như mail.config
Thuộc tính Network Mô tả
DefaultCredentials Một giá trị kiểu bool chỉ ra rằng các chứng thực của ứng
dụng có được dùng hay không. Nếu giá trị đó là true thì UserName và Password là không cần
Host Tên của máy chủ thư điện tử
UserName Tên người dùng được sử dụng để đăng nhập vào máy chủ thư điện tử và gửi thư.
Password Mật khẩu được sử dụng để đăng nhập vào máy chủ thư điện
tử để gửi thư
Port Cổng sẽ được sử dụng để gửi SMTP
Thuộc tính
Newsletters
Mô tả
FromEmail Địa chỉ thư điện tử thực sẽ xuất hiện trong mục “From” trong thư gửi đi ở phần đầu của thư
Hình 3.13 – Sơ đồ Model Newsletter
4.7. Controller
Với các chức năng của module như sơ đồ chức năng ta có tương ứng các phương thức hành động của controller của module
Phương thức hành động Bảo mật Các tham số
Index ---- ----
ManageNewsletters Editor ----
UpdateStatus Editor ----
CreateNewletters Editor string subject , string body
EditNewsletters Editor int? newsletterId, string subject, string body
RemoveNewsletter Editor int? newsletterId
4.8. View
Từ các phương thức hành động trong phần controller ta cũng có các view dành
cho tương ứng . Dưới đây là danh sách các view của module
Tên trang Đặc tả Đường dẫn ảo
Index.aspx Trang này được sử
dụng đểđăng kí
nhận thư từ hệ
thống
newsletter
CreateNewsletter.aspx Trang này cho
phép người dùng với vai trò là editor tạo hoặc chỉnh sửa thư editor/newsletter/create editor/newsletter/edit/{newsletterId}
thư và xem lại nội
dung thư hoặc xóa
thư. Trang được cập nhật sau vài giây xử dụng JQuery
4.9. Cấu hình định tuyến
Định tuyến cho trang index của module:
routes.MapRoute(
"NewsletterIndex", "newsletters",
new { controller = "Newsletter", action = "Index" } );
Định tuyến cho các trang dành cho editor: routes.MapRoute(
"NewsletterCreate",
"editor/newsletters/create",
new { controller = "Newsletter", action = "CreateNewsletter" }
);
routes.MapRoute( "NewsletterEdit",
"editor/newsletters/edit/{newsletterId}", new { controller = "Newsletter", action = "EditNewsletter", newsletterId = (int?)null },
new { newsletterId = "[0-9]+" } );
routes.MapRoute(
"NewsletterRemove",
"editor/newsletters/remove/{newsletterId}", new { controller = "Newsletter", action = "RemoveNewsletter", newsletterId = (int?)null },
new { newsletterId = "[0-9]+" } );
routes.MapRoute(
"NewsletterManage", "admin/newsletters",
new { controller = "Newsletter", action = "ManageNewsletters" }
uc Polls Editor (from Actors) Registered User (from Actors) View Polls Vote M anage Polls Remov e Poll Edit Poll Set Archiv e
Set Make Current
Create Poll Make Poll Question
Make Poll Options Update Poll «include» «include» «include» «include» «include» «include» «include»
5. MODULE LẤY Ý KIẾN KHÁCH HÀNG 5.1. Tổng quan về module
Module lấy ý kiến khách hàng gồm các câu hỏi đi kèm với mỗi câu hỏi là các lựa
chọn mà khách hàng có thể chọn để trả lời câu hỏi đó.
Module được xây dựng vì những lí do như người quản lí hệ thống muốn nắm bắt
thị hiếu khách hàng về nhiều vấn đề từ hệ thống cho đến các sản phẩm bán trong
siêu thị …Ngoài ra module được xây dựng cũng đem lại cho khách hàng cảm giác
họ là một phần của hệ thống và như vậy họ sẽ sử dụng hệ thốngthường xuyên
hơn.
Về mặt chức năng thì module sẽ cho người dùng xem các chưng cầu có trong hệ
thống (polls) , cho ý kiến (vote) . Với người dùng có vai trò là editor có thể quản lí các chưng cầu (chuyển chưng cầu sang trạng thái đã lấy đủ ý kiến - archive, hiện
hành, chỉnh sửa chưng cầu, xóa chưng cầu) , tạo chưng cầu mới
5.3. Các bảng dữ liệu
Hình 3.15 – Sơ đồ mối quan hệ giữa 2 bảng DL của module lấy ý kiến người dùng Với module này ta cần 2 bảng một bảng là bảng Polls chứa các câu hỏi lấy ý kiến
và các thuộc tính của chúng như câu hỏi chưng cầu là hiện hành – current , hay đã lấy đủ ý kiến – archived…
Bảng thứ 2 là bảng PollOptions chứa các thông tin về những chọn lựa cho câu hỏi đặt ra để lấy ý kiến. Mỗi một chọn lựa – options tương ứng với một câu trả lời được hệ thống tạo sẵn cho người dùng.Quan hệ giữa 2 bảng này được tạo thông
qua khóa ngoại PollD
Hình 3.17 – Sơ đồ thiết kế bảng Polls
5.4. Thiết kế lớp cấu hình cho module
Với module này cần thiết lập một số thông tin cấu hình như thiết lập thuộc tính
archived hay public cho một chưng cầu … (khi thiết lập thuộc tính public hay archived cho poll, cho phép hay không cho phép vote nhiều lần ..)
Bảng dưới đây sẽ là bảng các thuộc tính thuộc lớp PollElement . Lớp này kế thừa
từ lớp ConfigurationElement của framework .net mvc. Nó sẽ đọc các thiết lập của
thành phần <polls> nằm trong phần thiết lập cầu hình của <GlobalStore> trong tệp
web.config
5.5. Model
Model của module này cũng thiết kế theo kiểu mẫu Provider Model của Microsoft như đã trình bày trong phần lựa chọn kiến trúc hệ thống. Có 2 lớp thực thể LINQ- Thuộc tính SMTP Mô tả
VotingLockInterval Một số nguyên cho biết khi nào thì cookie dành cho phần
vote của một người dùng cụ thể nào đó hết hiệu lực (tương ứng với số ngày ngăn ngừa việc vote lại)
VotingLockByCookie Một giá trị kiểu bool chỉ ra rằng liệu cookie có được dùng hay
không được dùng cho việc nhớ người dùng đã vote hay
chưa
VotingLockByIP Một giá trị kiểu bool cho biết liệu địa chỉ IP của người dùng
có được giữ trong bộ nhớ để tránh việc một người với cùng 1
địa chỉ IP trong phiên hiện hành vote cho cùng một poll nhiều
lần
ArchiveIsPublic Một giá trị kiểu bool được dùng để cho biết liệu các poll đã
được thiết lập archive có được xem bởi tất cả mọi người hay
Hình 3.18 – Sơ đồ lớp PollOption và Poll
Lớp tĩnh PollQueries chứa tất cả các truy vấn cần thiết để lấy thông tin từ CSDL cụ
thể nó cung cấp các phương thức mở rộng cho module này.
Hình 3.19 – Sơ đồ lớp PollQueries
5.6. Controller
Ứng với các chức năng của module ta có các phương thức hành động trong
controller của module ở bảng dưới đây
Phương thức hành động Bảo mật Các tham số
Index ---- bool? archived, int page
ViewPoll ---- int id, string path
Vote ---- int optionId
ManagePolls Editor int page
CreatePoll Editor string question, bool? Current
RemovePoll Editor int? newsletterId
EditPoll Editor int pollId, string question, bool? current, bool?
Archived
AddOption Editor int pollId, string text
RemoveOption Editor int optionId
SetCurrent Editor int pollId
5.7. View
Dưới đây là các trang – view của module dành cho người dùng có vai trò editor và
người dùng khác của hệ thống:
Tên trang Đặc tả Đường dẫn ảo
Index.aspx Trang này được sử
dụng để xem các poll ở các trạng thái
như công khai (public) , đã lấy đủ (archived) /polls /polls/page{page} /polls?archived=true /polls/ page{page}?archived=true
CreatePoll.aspx Trang này cho
phép người dùng với vai trò là editor tạo hoặc chỉnh sửa poll /editor/polls/create / editor /polls/edit/{pollId}
ManagePolls.aspx Trang này liệt kê
toàn bộ các poll có trong hệ thống. Editor có thể thêm, chỉnh sửa, xóa các lựa chọn của poll, thiết lập poll hiện hành (set current), và xem poll hiện hành / editor /polls / editor /polls/page{page}
RemovePoll.aspx Trang này dùng
thực hiện việc xóa poll khỏi hệ thống
/editor/polls/remove/{pollId}
5.8. Sử dụng javascript
Module này sử dụng 2 tệp javascript trong thư mục Content/script là tệp manage- poll.js :
/****************************************************************** * Manage
******************************************************************/ $(document).ready(function() {
$("#polls :input").hide("fast");
});
"/poll/setcurrent", { pollId: id },
function(data) {
var poll = $("#set-current-" + data.object.pollId); poll.remove(); }, "json" ); return false; });
$(".set-archived").click(function() {
var id = $(this).attr("meta:id"),
archived = $(this).hasClass("archived"); $.post(
"/poll/setarchived",
{ pollId: id, archive: !archived },
function(data) {
var poll = $("#set-archived-" + data.object.pollId);
poll.removeClass("archived");
if (data.object.isArchived) poll.addClass("archived");
poll.text(data.object.isArchived ? "Allow Voting"
: "Archive"); }, "json" ); return false; }); /****************************************************************** * Polls ******************************************************************/
$("#question").focus(function() { ShowMessage(this, "Enter the
question you would like to ask in the poll."); });
function ValidateQuestion() {
return VerifyRequiredField("#question", "required");
}
function ValidatePoll() {
return ValidateQuestion();
$("form.poll-create").validate(ValidatePoll);
function EditOption() {
var id = $(this).attr("meta:id"), option = $("#option-" + id),
text = option.find(".text").text(); // hide all the childrend
option.children().hide();
var optionForm = $("<form><span class=\"field\"><input
type=\"text\" id=\"text-" + id + "\" class=\"edit-text\" value=\""
+ text + "\" /> <button type=\"button\" class=\"update\"
meta:id=\"" + id + "\">Update</button> <button type=\"button\"
class=\"cancel\">Cancel</button></span></form>");
// update the form
optionForm.find(".update").click(function () {
var id = $(this).attr("meta:id"),
formText = $(this).prevAll(".edit-text").val(); $.post(
"/poll/editoption",
{ optionId: id, text: formText },
function (data) {
var comment = $("#option-" + data.object.optionId);
comment.children("form").remove(); comment.children(".text").text(data.object.text);
comment.children().show(); },
"json"
); });
// cancel the update
optionForm.find(".cancel").click(function () {
$(this).parents(".option").children(":hidden").show(); $(this).parents("form").remove();
});
// add the form to the current comment option.append(optionForm);
return false;
function DeleteOption () {
var id = $(this).attr("meta:id"); $.post(
"/poll/removeoption",
{ optionId: id },
function (data) {
$("#option-" +
data.object.optionId).fadeOut("slow", function () { $(this).remove() }); }, "json" ); return false; } $(".delete-option-button").click(DeleteOption); function AddOptionSuccess(data) {
var optionItem = $("<li id=\"option-" + data.object.optionId
+ "\" class=\"option\"><span class=\"text\">" + data.object.text +
"</span> <button type=\"button\" class=\"edit-option-button\"
meta:id=\"" + data.object.optionId + "\">Edit</button> <button
type=\"button\" class=\"delete-option-button\" meta:id=\"" +
data.object.optionId + "\">Delete</button></li>");
optionItem.find(".edit-option-button").click(EditOption); optionItem.find(".delete-option-button").click(DeleteOption); // clear the option box
$("#option").val("");
// add the new option to the other options optionItem.appendTo("#poll-options"); }
$("form.poll-options-create").submit(function() {
var option = $("#option").val(), pollId = $("#pollId").val(); $.post(
"/poll/addoption",
{ pollId: pollId, text: option }, AddOptionSuccess, "json" ); return false; }); Và tệp poll.js
/****************************************************************** * Poll
******************************************************************/
function RenderPoll(obj, data) {
var poll = $(obj),
total = data.object.total,
item, percentValue, rightValue, leftValue; // clears all child nodes
poll.empty();
poll.append("<h2>" + data.object.question + "</h2>"); poll.append("<ul class=\"poll-options\">");
// go through each option and render it
for(var i = 0; i < data.object.options.length; i++) { item = data.object.options[i];
percentValue = Math.round(item.votes / total * 100); poll.append("<li class=\"option\" id=\"option-" + item.optionId + "\">"
+ "<h3>" + item.text + "</h3>"
+ "<div class=\"graph\"><img src=\"/Content/images/poll-
graph.gif\" height=\"10\" width=\"" + percentValue + "%\" /></div>"
+ "<div class=\"values\">" + percentValue + "% (" +
item.votes + " votes)</div>"
+ "</li>"); }
poll.append("</ul>");
poll.append("<div class=\"total\">There are " + total + "
total votes for this poll.</div>");
}
$(".poll form").submit(function() {
var selection = $(this).find(":checked").val();
if (selection != undefined) { $.post(
"/poll/vote",
{ optionId: selection },
function(data, textStatus) {
SetCookie("poll_" + data.object.pollId, selection, 30);
// render the poll for the given data
RenderPoll($("#poll-" + data.object.pollId), data);
); }
return false;
});
5.9. Cấu hình định tuyến
Định tuyến của các trang dành cho người dùng không có vai trò editor routes.MapRoute(
"PollsIndex", "polls",
new { controller = "Poll", action = "Index", page = 1 } );
routes.MapRoute(
"PollsIndexPaged", "polls/page{page}",
new { controller = "Poll", action = "Index", page = (int?)null }, new { page = "[0-9]+" }
);
Định tuyến dành của các trang dành cho người dùng có vai trò là editor routes.MapRoute(
"PollCreate",
"admin/polls/create",
new { controller = "Poll", action = "CreatePoll" } );
routes.MapRoute( "PollEdit",
"admin/polls/edit/{pollId}",
new { controller = "Poll", action = "EditPoll", pollId = (int?)null }, new { pollId = "[0-9]+" }
);
routes.MapRoute( "PollRemove",
"admin/polls/remove/{pollId}",
new { controller = "Poll", action = "RemovePoll", pollId = (int?)null }, new { pollId = "[0-9]+" }
);
routes.MapRoute(
"PollManager", "admin/polls",
new { controller = "Poll", action = "ManagePolls", page = 1 } );
routes.MapRoute(
"admin/polls/page{page}",
new { controller = "Poll", action = "ManagePolls", page = (int?)null }, new { page = "[0-9]+" }
uc Forums
Editor
(from Actors)
User
(from Actors)
View All Forums
View Forum View Post Create Post M anage Forum Edit Forum Remov e Forum Close Post Approv e Post Remov e Post «include» «include» 6. MODULE DIỄN ĐÀN 6.1. Tổng quan về module
Là một công ty sở hữu các chuỗi siêu thị có mặt khắp nơi trên thế giới ,Global Store có rất nhiều khách hàng trung thành. Các khách hàng của Global Store có
chung nhiều sở thích mà mua sắm tại các siêu thị của công ty là một trong những
sở thích đó.
Nhu cầu giao lưu trao đổi về những sở thích đó là hết sức tự nhiên . Nắm bắt được điểm này Global Store đã xây dựng diễn đàn tạo một sân chơi cho các
khách hàng của công ty giao lưu . Diễn đàn góp phần giữa chân các khách hàng trung thành cũng như biến các khách hàng tiềm năng thành khách hàng thân thiết
của công ty.
Sử dụng module này người dùng nạc danh có thể duyệt xem bài bình luận trong
các diễn đàn , tuy nhiên để gửi bài hay bình luận họ phải đăng nhập vào hệ thống.
Chức năng quản lí diễn đàn, quản lí các bài thỏa luận dành cho người dùng có vai trò là editor. (biên tập)
6.2. Sơ đồ chức năng
6.3. Các bảng dữ liệu
Hình 3.21 – Các bảng dữ liệu của module forum
Trong module này ta cần có 3 bảng như hình vẽ. Ngoài 2 bảng Forums và Posts là các bảng cốt lõi cho một diễn đàn thì ta có thêm bảng vote dùng cho cho ý kiến
một cho một post là hay hay không để người dùng có thể biết post đó được nhiều hay ít người quan tâm , thích.