Professional Documents
Culture Documents
Mau Trinh Bay-Tieu Luan-Lap Trinh Mobile
Mau Trinh Bay-Tieu Luan-Lap Trinh Mobile
Nhóm sinh viên thực hiện: Nguyễn Văn Phú Quí MSSV: 2254810032
i
MỤC LỤC
NHẬN XÉT CỦA GIẢNG VIÊN ...........................................................................1
LỜI MỞ ĐẦU...........................................................................................................
2. Cơ sở dữ liệu .............................................................................................
ii
DANH MỤC HÌNH ẢNH
(Danh mục hình ảnh trong Đề tài)
iii
DANH MỤC BẢNG BIỂU
iv
DANH MỤC THUẬT NGỮ VÀ TỪ VIẾT TẮT
(Danh mục các thuật ngữ và từ viết tắt trong Đề tài nếu có)
v
LỜI NÓI ĐẦU
Trong thời đại hiện nay, sự tiến bộ của khoa học và công nghệ đã mang lại những
cơ hội và lợi ích vô cùng quan trọng cho cuộc sống hàng ngày. Việc ứng dụng công nghệ
vào các lĩnh vực đời sống không chỉ giúp tăng hiệu quả công việc mà còn đóng góp tích
cực vào sự phát triển của cá nhân, cộng đồng và quốc gia. Các ngành nghề trong xã hội
ngày nay đều đã áp dụng công nghệ và kỹ thuật vào sản xuất và quản lý, từ đó tạo ra năng
suất cao hơn và giảm thiểu thời gian làm việc, góp phần thúc đẩy sự phát triển kinh tế.
Trong lĩnh vực quản lý, việc áp dụng công nghệ máy tính thay cho phương pháp
quản lý thủ công đã trở nên cực kỳ cần thiết. Điển hình là việc quản lý chi tiêu cá nhân,
một nhiệm vụ mà trước đây thường được thực hiện qua việc ghi chép trên giấy tờ, mất
thời gian và dễ gây bất tiện. Tuy nhiên, trong thời đại Công Nghệ 4.0 hiện nay, việc này
trở nên quá lỗi thời và không hiệu quả.
Để đáp ứng nhu cầu này, nhóm chúng tôi đã quyết định phát triển ứng dụng "Quản
Lý Chi Tiêu ". Mục tiêu của chúng tôi là giúp mọi người dễ dàng hơn trong việc quản lý
thông tin cá nhân mà không gặp phải các vấn đề như mất thời gian, khó bảo quản giấy tờ,
hoặc rủi ro bị ướt rách. Chúng tôi tin rằng, thông qua công nghệ, mọi người có thể tối ưu
hóa quản lý chi tiêu cá nhân của mình một cách thông minh và tiện lợi.
vi
CHƯƠNG I. GIỚI THIỆU
Nhu cầu thị trường : Việc quản lý chi tiêu là một nhu cầu cấp thiết trong xã hội ngày
nay. Với cuộc sống diễn ra nhanh chóng và ngày càng phức tạp, mọi người cần một
công cụ hiệu quả để kiểm soát tài chính của mình.
Tính ứng dụng cao : Ứng dụng quản lý chi tiêu có thể áp dụng cho mọi đối tượng, từ
sinh viên, người đi làm đến những người kinh doanh. Điều này tạo ra một thị trường
tiềm năng rộng lớn cho ứng dụng của chúng tôi.
Cơ sở thực tiễn: Tiến hành khảo sát để hiểu rõ hơn về nhu cầu và mong muốn của
người dùng trong việc quản lý chi tiêu cá nhân. Phân tích các ứng dụng tương tự đã có
trên thị trường để tìm ra điểm mạnh và điểm yếu, từ đó xác định những tính năng quan
trọng cần có trong ứng dụng của chúng tôi.Tập trung vào việc tạo ra một giao diện
người dùng thân thiện và dễ sử dụng. Chúng tôi sẽ tiến hành các buổi thảo luận, phân
tích và thiết kế để đảm bảo rằng trải nghiệm sử dụng của người dùng là tốt nhất có thể.
Thu thập các phản hồi và cải thiện ứng dụng.
1
CHƯƠNG II. CƠ SỞ LÝ THUYẾT
PostgreSQL là một hệ quản trị cơ sở dữ liệu mã nguồn mở phổ biến, được phát triển và duy
trì bởi cộng đồng lập trình viên toàn cầu. Nó là một hệ quản trị cơ sở dữ liệu mạnh mẽ, linh
hoạt và có khả năng mở rộng, thích hợp cho các ứng dụng từ quy mô nhỏ đến quy mô lớn.
Nó cũng có thể tích hợp dễ dàng với các ngôn ngữ lập trình phổ biến như Python, Java, PHP
và Ruby.
-Tính mở và miễn phí : PostgreSQL là một phần mềm mã nguồn mở và hoàn toàn
miễn phí để sử dụng, giúp giảm bớt chi phí cho doanh nghiệp và các dự án phần mềm.
- Độ tin cậy và ổn định : PostgreSQL được biết đến với độ ổn định cao và khả năng
xử lý dữ liệu lớn một cách hiệu quả. Nó có thể chạy trong môi trường sản xuất và đảm bảo
rằng dữ liệu của bạn luôn được bảo vệ và sẵn sàng sử dụng.
2
-Tính linh hoạt và mở rộng : PostgreSQL hỗ trợ nhiều tính năng linh hoạt như truy
vấn phức tạp, hàm địa chỉ, chức năng mở rộng và giao dịch song song. Điều này giúp
PostgreSQL phù hợp với nhiều loại ứng dụng và có thể mở rộng để đáp ứng nhu cầu của
doanh nghiệp.
- Bảo mật cao : PostgreSQL cung cấp các tính năng bảo mật mạnh mẽ như kiểm soát
truy cập, mã hóa dữ liệu và xác thực đáng tin cậy. Điều này giúp bảo vệ dữ liệu của bạn
khỏi các mối đe dọa và tấn công từ bên ngoài.
2.3 Nestjs
NestJS là một framework Node.js mã nguồn mở được xây dựng trên cơ sở TypeScript, được
thiết kế để tạo ra các ứng dụng máy chủ hiệu quả và dễ bảo trì. NestJS kết hợp các nguyên
tắc của Angular, cũng như các khái niệm từ Express và Node.js, để cung cấp một cách tiếp
cận có cấu trúc và tổ chức cho việc phát triển ứng dụng backend.
- Thúc đẩy sử dụng TypeScript : NestJS sử dụng TypeScript làm ngôn ngữ chính để
phát triển ứng dụng, giúp tăng cường tính rõ ràng và dễ bảo trì của mã nguồn. TypeScript
cung cấp các tính năng như kiểu dữ liệu tĩnh và mô-đun, giúp giảm thiểu lỗi trong quá trình
phát triển.
- Kiến trúc module và dependency injection : NestJS sử dụng kiến trúc module để tổ
chức mã nguồn một cách cấu trúc và dễ quản lý. Dependency injection (DI) được tích hợp
sẵn giúp tạo ra các thành phần tái sử dụng và dễ dàng thay đổi.
- Hỗ trợ đa nền tảng : NestJS hỗ trợ nhiều loại ứng dụng backend, bao gồm HTTP
server, gRPC server, WebSockets và microservices. Điều này giúp cho việc xây dựng các
ứng dụng có thể mở rộng và linh hoạt.
- Middleware và Pipes : NestJS cung cấp middleware và pipes để xử lý các yêu cầu
HTTP và xác thực dữ liệu đầu vào một cách dễ dàng. Điều này giúp tạo ra các ứng dụng an
toàn và tin cậy.
- Tích hợp sẵn với các thư viện và công nghệ khác : NestJS tích hợp sẵn với nhiều
thư viện và công nghệ phổ biến như TypeORM, Mongoose, GraphQL, WebSockets, gRPC,
và nhiều hơn nữa. Điều này giúp giảm thời gian phát triển và tăng cường khả năng mở rộng
của ứng dụng.
3
2.4 Redis
Redis là một hệ thống cơ sở dữ liệu mã nguồn mở, được phát triển với mục đích cung cấp
một cơ sở dữ liệu có khả năng lưu trữ và truy xuất dữ liệu nhanh chóng. Redis được thiết kế
để hoạt động như một cache, cơ sở dữ liệu key-value, và cũng có thể được sử dụng như một
message broker hoặc hàng đợi (queue).
- Hiệu suất cao và thời gian phản hồi nhanh : Redis được thiết kế để hoạt động với
hiệu suất cao và thời gian phản hồi nhanh. Nhờ vào cấu trúc dữ liệu trong bộ nhớ chính (in-
memory), Redis có thể xử lý hàng ngàn và thậm chí hàng triệu yêu cầu mỗi giây.
- Cấu trúc dữ liệu linh hoạt : Redis hỗ trợ nhiều cấu trúc dữ liệu như Strings, Lists,
Sets, Hashes, và Sorted Sets, cho phép phát triển ứng dụng một cách linh hoạt và hiệu quả.
- Công cụ cache mạnh mẽ : Redis thường được sử dụng như một công cụ cache để
lưu trữ dữ liệu tạm thời, giúp tăng tốc độ truy xuất dữ liệu từ cơ sở dữ liệu chính và giảm tải
cho hệ thống.
- Hỗ trợ hàng đợi và message broker : Redis có thể được sử dụng như một hàng đợi
hoặc message broker để xử lý các tác vụ không đồng bộ, đảm bảo tính nhất quán và đáp ứng
cao hơn cho ứng dụng.
Bull Queue là một thư viện Node.js mã nguồn mở, được sử dụng để quản lý và điều phối
các công việc (jobs) trong ứng dụng. Nó được xây dựng trên cơ sở Redis, một cơ sở dữ liệu
key-value, để cung cấp một cách tiếp cận đơn giản và hiệu quả cho việc xử lý hàng đợi
(queue) trong các ứng dụng Node.js.
- Độ tin cậy và nhất quán : Bull Queue sử dụng Redis để lưu trữ các công việc trong
hàng đợi, giúp đảm bảo tính nhất quán và độ tin cậy của hệ thống. Công việc không bị mất
và luôn được xử lý theo đúng thứ tự.
- Xử lý công việc bất đồng bộ : Bull Queue cho phép bạn xử lý các công việc bất
đồng bộ một cách dễ dàng và linh hoạt. Điều này giúp tăng tốc độ và hiệu suất của ứng dụng
bằng cách cho phép các tác vụ chậm chạp hoặc tốn nhiều thời gian được thực hiện mà
không làm gián đoạn luồng chính của ứng dụng.
4
- Thời gian chờ và xử lý độ trễ : Bull Queue cung cấp các tính năng như thời gian
chờ (delayed jobs) và xử lý độ trễ (retry jobs) để giúp bạn điều chỉnh và quản lý việc xử lý
các công việc theo cách linh hoạt nhất.
- Khả năng mở rộng và phân tán : Bull Queue cho phép bạn mở rộng hệ thống của
mình một cách dễ dàng bằng cách thêm các worker hoặc máy chủ Redis mới. Điều này giúp
tăng khả năng xử lý và sẵn sàng của hệ thống khi nhu cầu tăng cao.
2.6 Docker
Docker là một nền tảng mã nguồn mở giúp bạn tạo, triển khai và chạy các ứng dụng trong
các môi trường container. Mỗi container trong Docker chứa một ứng dụng cùng với tất cả
các thư viện và phụ thuộc cần thiết, tạo ra một môi trường độc lập và đồng nhất cho việc
phát triển và chạy ứng dụng.
- Tính di động và đóng gói : Docker cho phép bạn đóng gói ứng dụng và môi trường
của nó vào các container, giúp di động ứng dụng một cách dễ dàng giữa các môi trường
khác nhau, từ máy tính cá nhân đến máy chủ điện toán đám mây.
- Tiết kiệm tài nguyên : Docker sử dụng cùng một hạt nhân hệ điều hành với máy chủ
host, giúp tiết kiệm tài nguyên hệ thống và tối ưu hóa hiệu suất. Điều này cho phép bạn chạy
nhiều container trên cùng một máy mà không gặp vấn đề về tài nguyên.
- Tính nhất quán giữa môi trường phát triển và triển khai : Docker giúp đảm bảo tính
nhất quán giữa môi trường phát triển và môi trường triển khai bằng cách đóng gói ứng dụng
và tất cả các phụ thuộc của nó vào container.
- Tính cô đọng và linh hoạt : Docker cho phép bạn tạo ra các container nhẹ và cô
đọng, giúp tối ưu hóa thời gian triển khai và giảm bớt khối lượng dữ liệu cần truyền tải.
5
- Không phụ thuộc vào ngôn ngữ lập trình hoặc nền tảng
2.7.3 Mô hình Client-Server
Mô hình Client-Server là một mô hình kiến trúc phần mềm trong đó các ứng dụng được chia
thành hai phần chính: máy khách (client) và máy chủ (server). Máy khách gửi yêu cầu đến
máy chủ và máy chủ trả về phản hồi cho máy khách.
6
CHƯƠNG III. PHÂN TÍCH VÀ THIẾT KẾ GIAO DIỆN HỆ
THỐNG
3.1. Phân tích hệ thống
3.1.1. Khảo sát yêu cầu
Mục Đích Ứng Dụng
- Mục tiêu chính: Cung cấp công cụ đơn giản và hiệu quả để người dùng
quản lý chi tiêu hàng ngày.
- Lợi ích: Giúp người dùng kiểm soát tài chính cá nhân, theo dõi thu nhập và
chi tiêu, đặt mục tiêu tiết kiệm, và nhận nhắc nhở về các khoản chi tiêu cần
thiết.
Đối Tượng Sử Dụng
- Đối tượng: Tất cả các cá nhân muốn quản lý tài chính cá nhân.
Yêu Cầu Chức Năng
- Tài Khoản Người Dùng
+ Đăng ký/Đăng nhập
+ Tùy chọn đăng ký/đăng nhập bằng mạng xã hội:
+ Khôi phục mật khẩu
- Quản Lý Thu Nhập và Chi Tiêu
+ Thêm khoản thu:
+ Thêm khoản chi:
+ Chỉnh sửa khoản thu/chi:
+ Xóa khoản thu/chi:
- Danh Mục
+ Thêm danh mục thu/chi
+ Chỉnh sửa danh mục thu/chi
+ Xóa danh mục thu/chi
- Quản Lý Tài Khoản
+ Tạo số tiền tài khoản
+ Chỉnh sửa và xóa tài khoản:
7
- Nhắc Nhở
+ Tạo nhắc nhở:
- Cài Đặt
+ Chọn loại tiền tệ
+ Đổi, tạo, xóa mã PIN
+ Tùy chọn ngôn ngữ:
+ Xóa tất cả dữ liệu người dùng:
- Hỗ Trợ
+ Liên hệ nhóm hỗ trợ:
3.1.2. Chức năng hệ thống
Tác nhân hệ thống (người sử dụng)
Người dùng:
+ Quản lý hồ sơ
+ Liên hệ hỗ trợ
8
9
10
11
Đặc tả chức năng (đặc tả các chức năng của hệ thống)
1. Đăng Ký:
- Người dùng chọn profile tại mục Account – My Account.
- Nếu chưa có tài khoản, người dùng chọn đăng ký.
- Thông tin đăng ký: Email, mật khẩu (có thể hiện/ẩn mật khẩu).
2. Đăng Nhập:
- Sau khi đăng ký, người dùng chuyển qua đăng nhập.
- Thông tin đăng nhập: Email, mật khẩu (có thể hiện/ẩn mật khẩu), quên mật
khẩu.
12
3.Khôi Phục Mật Khẩu: Ở trang đăng nhập, nếu người dùng không nhớ mật khẩu,
họ chọn tính năng quên mật khẩu. Hệ thống sẽ gửi mã OTP đến điện thoại hoặc email
để xác nhận và đặt lại mật khẩu.
4.Đăng Ký Bằng Facebook: Người dùng chọn đăng ký bằng Facebook sẽ chuyển
sang giao diện đăng nhập Facebook. Chỉ cần nhập tài khoản Facebook, người dùng sẽ
đăng nhập thành công.
5. Thêm Danh Mục:
- Sau khi nhập số tiền, người dùng chọn danh mục từ danh sách mặc định hoặc
thêm mới bằng cách nhấp vào dấu cộng.
- Tạo danh mục mới bằng cách nhập tên và chọn màu, sau đó nhấn nút thêm.
6. Chỉnh Sửa Danh Mục:
- Nhấp vào nút chỉnh sửa trên activity của khoản thu/chi.
- Chỉnh sửa tên danh mục và nhấn nút lưu để hoàn tất.
7. Xóa Danh Mục:
- Nhấp vào nút xóa trên activity của khoản thu/chi.
- Xác nhận xóa trong activity hiển thị và nhấn nút xóa để hoàn tất.
8. Tạo Số Tiền Tài Khoản: Người dùng chọn mục "Wallet", ở đây người dùng có
thể tạo ra tài khoản mới với mục đích tùy sử dụng của người dùng. Khi tạo xong
người dùng có thể tạo ra giao dịch chi tiêu hay cho giao dịch cho chính tài khoản này.
9. Tạo Lời Nhắc:
- Nhấp vào biểu tượng hình cái chuông hoặc vào phần Profile và chọn
"Notification", sau đó nhấp vào dấu cộng.
- Nhập tên lời nhắc, tuần suất (một lần, hàng ngày, hàng tuần, hàng tháng, hàng
quý), chọn ngày và giờ nhắc, và thêm ghi chú nếu cần.
10. Chọn Đơn Vị Tiền Tệ:
- Người dùng có thể chọn đơn vị tiền tệ theo sở thích.
- Có nhiều đơn vị tiền tệ trên thế giới như USD (đô la Mỹ), JPY (yên Nhật),
KRW (won Hàn Quốc), VND (đồng Việt Nam)...
- Tìm Kiếm: Người dùng có thể tìm kiếm tiền tệ qua icon kính lúp
13
- Khi sử dụng lần đầu, hệ thống yêu cầu người dùng chọn loại tiền tệ mong
muốn.
11. Tạo, sửa, xóa Mã PIN:
- Nhấp vào "Đặt mã PIN" để nhập 4 chữ số mong muốn, sau đó nhập lại một
lần nữa để xác nhận.
- Nhấp vào "Đổi mã PIN" để nhập mã PIN cũ và đặt mã PIN mới.
- Chọn "Xóa mã PIN" và nhập mã PIN cũ để xác nhận xóa.
12. Thêm,sửa, xóa Khoản Thu:
- Thêm khoản thu: Nhập số tiền, chọn ngày tháng, và nhập tiêu đề của khoản
thu, tổng số tiền các khoản thu sẽ hiển thị trên màn hình chính.
- Chỉnh Sửa Khoản Thu: Nhấp vào khoản thu cần chỉnh sửa để sửa số tiền,
tiêu đề, danh mục, thời gian, loại tài khoản, nhấn nút lưu để thay đổi thành
công.
- Xóa Khoản Thu: Nhấp vào khoản thu cần xóa và chọn nút xóa, xác nhận
xóa trong activity hiển thị với cảnh báo, nhấn nút xóa để xóa thành công.
13. Thêm, sửa, xóa Khoản Chi:
- Thêm khoản chi: Nhập số tiền, chọn ngày tháng, và nhập tiêu đề của khoản
chi, tổng số tiền các khoản chi sẽ hiển thị trên màn hình chính.
- Chỉnh Sửa Khoản Chi: Nhấp vào khoản chi cần chỉnh sửa để sửa số tiền, tiêu
đề, danh mục, thời gian, loại tài khoản, nhấn nút lưu để thay đổi thành công.
- Xóa Khoản Chi: Nhấp vào khoản chi cần xóa và chọn nút xóa, xác nhận xóa
trong activity hiển thị với cảnh báo, nhấn nút xóa để xóa thành công.
14. Chọn Ngôn Ngữ:
- Trong activity Giao Diện, chọn mục Ngôn Ngữ.
- Hiển thị danh sách các ngôn ngữ theo kiểu Option Menu: English, Tiếng
Việt, v.v.
- Mặc định app sẽ là Tiếng Việt.
15. Xóa tất cả dữ liệu người dùng: Trong phần Profile, nhấp vào biểu tượng Cài
Đặt để chuyển đến Cài Đặt. Chọn mục "Xóa tất cả dữ liệu người dùng", sẽ hiển thị
14
lên thông báo cảnh báo và người dùng chấp nhận thì dữ liệu trên ứng dụng sẽ được
xóa hết, người dùng sử dụng ứng dụng như lần đầu đăng nhập
16. Liên Hệ Với Nhóm Hỗ Trợ: Trong phần Profile, nhấp vào biểu tượng Cài Đặt
để chuyển đến activity Cài Đặt. Chọn mục "Liên hệ với nhóm hỗ trợ" sẽ có thể:
- Chủ đề thư: Nhập tiêu đề (lỗi, góp ý, v.v.).
- Email người dùng: Để nhóm hỗ trợ trả lời qua email.
- Nội dung thư: Nhập chi tiết vấn đề hoặc góp ý.
15
Biểu đồ tương tác tuần tự
16
3.1.4. Biểu đồ lớp (Biểu đồ quan hệ thực thể ER)
17
password Mã password Varchar
first_name Tên đầu Varchar
last_name Tên cuối Varchar
avatar ảnh Varchar?
role_id Mã role bigint Khóa ngoại
created_at Thời gian tạo Timestamp
3.3. Các API và các hàm xử lý trong hệ thống (chỉ áp dụng với hệ thống sử dụng
API)
19
(Phần Thiết kế giao diện cho các chức năng trong hệ thống tùy theo mỗi hệ thống sẽ có các trình bày. Dưới
đây là các trình bày các các hệ thống ứng dụng web, app)
3.4. Giao diện và chức năng trên nền tảng di dộng cho người dùng
(3.6.1, 3.6.2, 3.6.3, …. Các giao diện và chức năng đã xây dựng trên nền tảng di động cho
người dùng)
Các hình phải tạo mục lục hình, có tên hình. Có giải thích chức năng tại các hình đó Chứ
không phải chụp hình để vào cho có nhé
20
CHƯƠNG IV. KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
4.1 Kết luận
4.1.1 So sánh kết quả nghiên cứu hoặc sản phẩm với các nghiên cứu hoặc sản phẩm
tương tự
So với các ứng dụng quản lý chi tiêu hiện có trên thị trường, "App Quản Lý Chi Tiêu" của
chúng tôi có những điểm khác biệt và ưu điểm nổi bật sau:
- Giao diện người dùng thân thiện và dễ sử dụng: Ứng dụng được thiết kế với giao
diện đẹp mắt, trực quan và dễ dàng sử dụng cho mọi đối tượng người dùng.
- Tính năng quản lý chi tiêu thông minh: Ứng dụng cho phép người dùng quản lý chi
tiêu hàng ngày một cách dễ dàng và hiệu quả, giúp họ theo dõi, phân loại và đánh giá
chi tiêu của mình.
- Công nghệ hiện đại: Ứng dụng được xây dựng dựa trên các công nghệ hiện đại như
Flutter, PostgreSQL, NestJS, Redis, Bull Queue và Docker, đảm bảo hiệu quả, mượt
mà và dễ dàng mở rộng.
- Hoàn thành đề tài "Lập trình thiết bị di động" với sản phẩm là ứng dụng quản lý chi
tiêu "App Quản Lý Chi Tiêu".
- Nâng cao kiến thức và kỹ năng lập trình di động, đặc biệt là về Flutter, PostgreSQL,
NestJS, Redis, Bull Queue và Docker.
- Áp dụng kiến thức và kỹ năng đã học vào thực tế để phát triển một sản phẩm hữu
ích cho người dùng.
- Rèn luyện kỹ năng làm việc nhóm, giao tiếp và quản lý thời gian.
- Quá trình phát triển ứng dụng di động đòi hỏi nhiều thời gian, công sức và sự kiên
trì.
- Cần có sự hiểu biết rõ ràng về nhu cầu của người dùng để thiết kế và phát triển một
ứng dụng phù hợp.
21
- Việc lựa chọn công nghệ phù hợp đóng vai trò quan trọng trong việc đảm bảo hiệu
quả và tính ổn định của ứng dụng.
- Cần có sự hợp tác chặt chẽ giữa các thành viên trong nhóm để hoàn thành dự án
một cách hiệu quả.
- Cải thiện tính năng quản lý và phân loại chi tiêu một cách linh hoạt và thông minh.
4.2.2 Phân tích các hướng đi mới cho phép cải thiện và nâng cấp các chức năng/nhiệm
vụ đã làm
- Sử dụng trí tuệ nhân tạo (AI) để đề xuất các mẹo quản lý chi tiêu và mục tiêu tiết
kiệm phù hợp với hành vi tiêu dùng của người dùng.
- Phát triển ứng dụng cho nhiều nền tảng di động khác nhau như iOS và web để mở
rộng phạm
22
TÀI LIỆU THAM KHẢO
(Tạo tài liệu tham khảo tự động, xem lại mục hướng dẫn)
23