You are on page 1of 26

BỘ GIÁO DỤC VÀ ĐÀO TẠO

TRƯỜNG ĐẠI HỌC SƯ PHẠM KỸ THUẬT TP.HCM

MÔN HỌC: THỰC TẬP HỆ THỐNG NHÚNG

BÁO CÁO CUỐI KỲ

Lớp thứ 4 tiết 7-11

GVHD: Ths. Đậu Trọng Hiển

Sinh viên MSSV

Lý Tấn Lộc 21139078

Võ Ngọc Linh 21139077

- Tp. Hồ Chí Minh, tháng 3 năm 2024 -


Mục lục
Bài 1: Cộng 2 số.............................................................................................................................................2
Bài 2: Calculator............................................................................................................................................4
Bài 3: Đồng hồ 3 kim...................................................................................................................................10
Bài 4: Chương trình quản lý kho sử dụng QR/BARCODE.........................................................................19

1
Bài 1: Cộng 2 số
Code:
import 'package:flutter/material.dart'; // Import thư viện flutter

void main() {
runApp(MyApp()); // Khởi chạy ứng dụng MyApp
}

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(), // Màn hình chính của ứng dụng là MyHomePage
);
}
}

class MyHomePage extends StatefulWidget {


@override
_MyHomePageState createState() => _MyHomePageState(); // Trạng thái
của màn hình là _MyHomePageState
}

class _MyHomePageState extends State<MyHomePage> {


TextEditingController number1Controller = TextEditingController();
// Controller cho TextField nhập số thứ nhất
TextEditingController number2Controller = TextEditingController();
// Controller cho TextField nhập số thứ hai
String result = ''; // Biến lưu kết quả tính toán

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Calculator'), // Tiêu đề của ứng dụng
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(

2
controller: number1Controller,
keyboardType: TextInputType.number,
decoration: InputDecoration(labelText: 'Enter number
1'), // TextField nhập số thứ nhất
),
TextField(
controller: number2Controller,
keyboardType: TextInputType.number,
decoration: InputDecoration(labelText: 'Enter number
2'), // TextField nhập số thứ hai
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
calculateSum(); // Gọi hàm tính tổng khi nhấn nút
},
child: Text('Calculate Sum'), // Nút tính tổng
),
SizedBox(height: 20),
Text('Result: $result'), // Kết quả tính toán
],
),
),
);
}

// Hàm tính tổng


void calculateSum() {
double number1 = double.tryParse(number1Controller.text) ?? 0.0;
// Lấy giá trị số thứ nhất từ TextField
double number2 = double.tryParse(number2Controller.text) ?? 0.0;
// Lấy giá trị số thứ hai từ TextField
double sum = number1 + number2; // Tính tổng
setState(() {
result = sum.toString(); // Cập nhật kết quả tính toán
});
}
}

3
Bài 2: Calculator
Code:
import 'dart:math'; // Import thư viện dart:math
import 'package:flutter/material.dart'; // Import thư viện flutter

void main() {
runApp(CalculatorApp()); // Khởi chạy ứng dụng CalculatorApp
}

class CalculatorApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, // Ẩn biểu tượng "debug" trên
banner
title: 'Calculator', // Tiêu đề của ứng dụng
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CalculatorScreen(), // Màn hình chính của ứng dụng là
CalculatorScreen
);
}
}

class CalculatorScreen extends StatefulWidget {


@override
_CalculatorScreenState createState() => _CalculatorScreenState(); //
Trạng thái của màn hình là _CalculatorScreenState
}

class _CalculatorScreenState extends State<CalculatorScreen> {


String _output = '0'; // Kết quả hiển thị trên màn hình
double _num1 = 0; // Số thứ nhất trong phép tính
double _num2 = 0; // Số thứ hai trong phép tính
String _operator = ''; // Toán tử của phép tính
double _previousResult = 0; // Biến thể hiện kết quả trước đó
bool isResultDisplayed = false; // Biến kiểm tra kết quả đã được
hiển thị hay chưa

// Hàm xử lý sự kiện khi nhấn nút

4
void _buttonPressed(String buttonText) {
setState(() {
if (isResultDisplayed && buttonText != '=') {
_output = '0';
isResultDisplayed = false;
}

if (buttonText == 'C') {
_output = '0';
_num1 = 0;
_num2 = 0;
_operator = '';
_previousResult = 0; // Xóa kết quả trước đó
} else if (isResultDisplayed && buttonText != '=') {
_output = '0';
isResultDisplayed = false;
} else if (buttonText == '+' ||
buttonText == '-' ||
buttonText == '*' ||
buttonText == '/') {
_num1 = double.parse(_output);
_operator = buttonText;
_output = '0';
} else if (buttonText == '=') {
_num2 = double.parse(_output);
if (_operator == '+') {
_output = (_num1 + _num2).toString();
} else if (_operator == '-') {
_output = (_num1 - _num2).toString();
} else if (_operator == '*') {
_output = (_num1 * _num2).toString();
} else if (_operator == '/') {
_output = (_num1 / _num2).toString();
}

if (_output.contains('.') &&
double.parse(_output) == double.parse(_output.split('.')
[0])) {
_output = int.parse(_output.split('.')[0]).toString();
}

_previousResult = double.parse(_output); // Cập nhật kết quả


trước đó
_num1 = 0;
_num2 = 0;
_operator = '';

5
isResultDisplayed = true;
} else if (buttonText == '√') {
_num1 = double.parse(_output);
_output = sqrt(_num1).toString();
} else if (buttonText == 'x^2') {
_num1 = double.parse(_output);
_output = (_num1 * _num1).toString();
} else if (buttonText == '⌫') {
// Xử lý xóa một chữ số
if (_output.length > 1) {
_output = _output.substring(0, _output.length - 1);
} else {
_output = '0';
}
} else {
if (_output == '0' && buttonText != '.') {
_output = buttonText;
} else if (buttonText == '.' && !_output.contains('.')) {
_output += buttonText;
} else if (buttonText != '.') {
_output += buttonText;
}
}
});
}

// Widget tạo nút


Widget _buildButton(String buttonText, Color buttonColor, Color
textColor,
{double height = 70.0, double width = 80.0}) {
return Container(
height: height,
width: width,
margin: EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () => _buttonPressed(buttonText),
style: ElevatedButton.styleFrom(
primary: buttonColor,
onPrimary: textColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: BorderSide(color: Colors.grey),
),
),
child: Text(
buttonText,

6
style: TextStyle(fontSize: 15.0, color: textColor),
),
),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Mai Đông Thức - Mã Quang Lộc',
style: TextStyle(fontSize: 20.0),
),
centerTitle: true,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
alignment: Alignment.bottomRight,
padding: EdgeInsets.all(24.0),
color: Colors.grey[200],
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
_previousResult.toString(),
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
color: Colors.grey,
),
),
SizedBox(height: 8.0),
Text(
_output,
style: TextStyle(
fontSize: 48.0,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
],
),

7
),
),
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildButton('√', Colors.grey[300]!, Colors.black),
_buildButton('x^2', Colors.grey[300]!, Colors.black),
_buildButton('⌫', Colors.grey[300]!, Colors.black),
_buildButton('/', Colors.orange, Colors.white),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildButton('7', Colors.grey[300]!, Colors.black),
_buildButton('8', Colors.grey[300]!, Colors.black),
_buildButton('9', Colors.grey[300]!, Colors.black),
_buildButton('*', Colors.orange, Colors.white),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildButton('4', Colors.grey[300]!, Colors.black),
_buildButton('5', Colors.grey[300]!, Colors.black),
_buildButton('6', Colors.grey[300]!, Colors.black),
_buildButton('-', Colors.orange, Colors.white),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildButton('1', Colors.grey[300]!, Colors.black),
_buildButton('2', Colors.grey[300]!, Colors.black),
_buildButton('3', Colors.grey[300]!, Colors.black),
_buildButton('+', Colors.orange, Colors.white),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildButton('C', Colors.red, Colors.white),
_buildButton('0', Colors.grey[300]!, Colors.black),
_buildButton('.', Colors.grey[300]!, Colors.black),
_buildButton('=', Colors.blue, Colors.white),

8
],
),
],
),
);
}
}

9
Bài 3: Đồng hồ 3 kim
Code:
import 'dart:async'; // Import thư viện cho việc sử dụng Timer
import 'dart:math'; // Import thư viện cho việc sử dụng hàm cos và sin
import 'package:flutter/material.dart'; // Import thư viện flutter

void main() {
runApp(MyClockApp()); // Khởi chạy ứng dụng Flutter
}

class MyClockApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, // Ẩn biểu tượng "debug" trên
banner
home: Scaffold(
appBar: AppBar(
title: Text('Mai Đông Thức - Mã Quang Lộc'), // Tiêu đề ứng
dụng
),
body: Container(
color: Color.fromARGB(255, 30, 53, 3), // Đặt màu nền là màu
đen
child: Center(
child: MyClock(), // Hiển thị đồng hồ
),
),
),
);
}
}

class MyClock extends StatefulWidget {


@override
_MyClockState createState() => _MyClockState(); // Tạo ra trạng thái
cho đồng hồ
}

class _MyClockState extends State<MyClock> {


DateTime _currentTime = DateTime.now(); // Lưu trữ thời gian hiện
tại
Timer? _timer; // Biến đếm thời gian

10
@override
void initState() {
super.initState();
_timer = Timer.periodic(Duration(seconds: 1), _updateTime); // Cập
nhật thời gian mỗi giây
}

@override
void dispose() {
_timer?.cancel(); // Hủy timer khi widget bị huỷ
super.dispose();
}

void _updateTime(Timer timer) {


setState(() {
_currentTime = DateTime.now(); // Cập nhật thời gian mới
});
}

@override
Widget build(BuildContext context) {
return Container(
width: 300, // Chiều rộng của đồng hồ
height: 300, // Chiều cao của đồng hồ
child: CustomPaint(
painter: ClockPainter(_currentTime), // Vẽ đồng hồ
),
);
}
}

class ClockPainter extends CustomPainter {


final DateTime time; // Thời gian hiện tại

ClockPainter(this.time);

@override
void paint(Canvas canvas, Size size) {
final centerX = size.width / 2; // Tọa độ x của tâm đồng hồ
final centerY = size.height / 2; // Tọa độ y của tâm đồng hồ
final center = Offset(centerX, centerY); // Tọa độ tâm đồng hồ

final radius = min(centerX, centerY); // Bán kính của đồng hồ

// Vẽ đường viền mặt đồng hồ


final borderPaint = Paint()

11
..color = Color.fromARGB(255, 40, 255, 86) // Màu viền đồng hồ
..style = PaintingStyle.stroke // Kiểu vẽ là nét kẻ
..strokeWidth = 20; // Độ dày của viền

canvas.drawCircle(
center, radius + 5, borderPaint); // Vẽ đường viền mặt đồng hồ
(thêm 5 để đẩy viền ra ngoài)

// Vẽ mặt đồng hồ
final facePaint = Paint()
..color = Color.fromARGB(255, 59, 79, 60) // Màu mặt đồng hồ
..style = PaintingStyle.fill; // Kiểu vẽ là toàn phần

canvas.drawCircle(center, radius, facePaint); // Vẽ mặt đồng hồ


// Vẽ các điểm chỉ số cho giờ và các đường nhỏ giữa chúng
final hourIndexPaint = Paint()
..color = Colors.white // Màu của các điểm chỉ số
..style = PaintingStyle.fill; // Kiểu vẽ là toàn phần

// Kích thước khoảng cách từ trung tâm đến các số giờ


final hourIndexRadius =
radius - 30; // Điều chỉnh giảm khoảng cách này để các số gần
viền hơn

final mainLinePaint = Paint()


..color = Colors.white // Màu của các đường chính lớn
..style = PaintingStyle.stroke // Kiểu vẽ là nét kẻ
..strokeWidth = 3; // Độ dày của các đường chính lớn

final smallLinePaint = Paint()


..color = Colors.white.withOpacity(0.4) // Màu của các đường nhỏ
giữa các số
..style = PaintingStyle.stroke // Kiểu vẽ là nét kẻ
..strokeWidth = 2; // Độ dày của các đường nhỏ giữa các số

for (int i = 1; i <= 60; i++) {


final angle = (i - 15) * 6 * (pi / 180); // Tính góc dựa trên số
giờ
final lineRadius = radius - (i % 5 == 0 ? 15 : 10); // Độ dài
của đường chỉ số

final startX = centerX + cos(angle) * lineRadius; // Tọa độ x


của điểm bắt đầu
final startY = centerY + sin(angle) * lineRadius; // Tọa độ y
của điểm bắt đầu

12
final endX = centerX + cos(angle) * radius; // Tọa độ x của điểm
kết thúc
final endY = centerY + sin(angle) * radius; // Tọa độ y của điểm
kết thúc

if (i % 5 == 0) {
// Nếu là số giờ, vẽ đường chính lớn
canvas.drawLine(
Offset(startX, startY), Offset(endX, endY),
mainLinePaint);
} else {
// Nếu không, vẽ đường nhỏ giữa các số
canvas.drawLine(
Offset(startX, startY), Offset(endX, endY),
smallLinePaint);
}
}

// Hàm _getRomanNumeral để chuyển đổi số sang số La Mã


String _getRomanNumeral(int value) {
final romanNumerals = [
"I",
"II",
"III",
"IV",
"V",
"VI",
"VII",
"VIII",
"IX",
"X",
"XI",
"XII"
];
return romanNumerals[value - 1];
}

// Vẽ các điểm chỉ số cho giờ


final textPainter = TextPainter(
textDirection: TextDirection.ltr,
);

for (int i = 1; i <= 12; i++) {


final hourAngle = ((i - 3) * 30) * (pi / 180); // Tính góc dựa
trên số giờ
final hourIndexOffset = Offset(

13
centerX + cos(hourAngle) * hourIndexRadius, // Tọa độ x của
điểm chỉ số
centerY + sin(hourAngle) * hourIndexRadius, // Tọa độ y của
điểm chỉ số
);

// Hiển thị số La Mã tương ứng với số giờ


final hourText = _getRomanNumeral(i);
textPainter.text = TextSpan(
text: hourText,
style: TextStyle(
color: Colors.white, // Màu của số giờ
fontSize: 24, // Kích thước của số giờ
fontWeight: FontWeight.bold, // Độ đậm của số giờ
),
);
textPainter.layout();

// Vẽ số giờ
textPainter.paint(
canvas,
Offset(
hourIndexOffset.dx - textPainter.width / 2, // Vị trí x của
số giờ
hourIndexOffset.dy - textPainter.height / 2, // Vị trí y của
số giờ
),
);
}

// Vẽ con số chỉ phút và giờ bên trong đồng hồ


_drawDigitalTime(canvas, centerX, centerY, time.hour,
time.minute);

// Vẽ thứ ngày
_drawDateAndDay(canvas, centerX, centerY, radius);

// Vẽ kim giờ, phút, giây và chấm chính giữa đồng hồ


_drawClockHands(canvas, center, radius);
}

// Hàm vẽ con số chỉ phút và giờ bên trong đồng hồ


void _drawDigitalTime(
Canvas canvas, double centerX, double centerY, int hours, int
minutes) {
final digitalTimeText =

14
'${_formatTwoDigits(hours)} : ${_formatTwoDigits(minutes)}';
// Chuỗi hiển thị thời gian

final digitalTimePainter = TextPainter(


text: TextSpan(
text: digitalTimeText,
style: TextStyle(
color: Colors.white, // Màu của con số chỉ phút và giờ
fontSize: 24, // Kích thước của con số chỉ phút và giờ
fontWeight: FontWeight.bold, // Độ đậm của con số chỉ phút
và giờ
),
),
textDirection: TextDirection.ltr,
);

digitalTimePainter.layout();

final digitalTimeX = centerX - digitalTimePainter.width / 2; // Vị


trí x của con số chỉ phút và giờ
final digitalTimeY = centerY - digitalTimePainter.height / 0.4; //
Vị trí y của con số chỉ phút và giờ

// Vẽ con số chỉ phút và giờ bên trong đồng hồ


digitalTimePainter.paint(canvas, Offset(digitalTimeX,
digitalTimeY));
}

// Hàm vẽ thứ và ngày bên dưới đồng hồ


void _drawDateAndDay(
Canvas canvas, double centerX, double centerY, double radius) {
final dayText = _getDayOfWeek(); // Lấy tên của ngày trong tuần
final dateText = _formatTwoDigits(time.day); // Lấy ngày hiện tại

final dayDateText = "$dayText, $dateText"; // Chuỗi hiển thị thứ


và ngày

final datePainter = TextPainter(


text: TextSpan(
text: dayDateText,
style: TextStyle(
color: Colors.white, // Màu của thứ và ngày
fontSize: 24, // Kích thước của thứ và ngày
fontWeight: FontWeight.bold, // Độ đậm của thứ và ngày
),
),

15
textDirection: TextDirection.ltr,
);

datePainter.layout();

final dateX = centerX - datePainter.width / 2; // Vị trí x của thứ


và ngày
final dateY = centerY + radius * 0.3; // Vị trí y của thứ và ngày

// Vẽ thứ và ngày bên dưới đồng hồ


datePainter.paint(canvas, Offset(dateX, dateY));
}

// Hàm vẽ kim giờ, phút, giây và chấm giữa đồng hồ


void _drawClockHands(Canvas canvas, Offset center, double radius) {
// Vẽ kim giờ
final hourPaint = Paint()
..color = Color.fromARGB(255, 249, 255, 86) // Màu của kim giờ
..style = PaintingStyle.stroke // Kiểu vẽ là nét kẻ
..strokeCap = StrokeCap.round // Kiểu đầu của kim giờ
..strokeWidth = 15; // Độ dày của kim giờ
final hourAngle =
((time.hour % 12 + time.minute / 60) - 3) * 30 * (pi / 180);
// Tính góc của kim giờ
canvas.drawLine(
center,
center +
Offset(cos(hourAngle) * radius * 0.5, sin(hourAngle) *
radius * 0.5),
hourPaint,
);

// Vẽ kim phút
final minutePaint = Paint()
..color = Colors.blue // Màu của kim phút
..style = PaintingStyle.stroke // Kiểu vẽ là nét kẻ
..strokeCap = StrokeCap.round // Kiểu đầu của kim phút
..strokeWidth = 10; // Độ dày của kim phút

final minuteAngle =
((time.minute + time.second / 60) - 15) * 6 * (pi / 180); //
Tính góc của kim phút
canvas.drawLine(
center,
center +
Offset(

16
cos(minuteAngle) * radius * 0.7, sin(minuteAngle) *
radius * 0.7),
minutePaint,
);

// Vẽ kim giây
final secondPaint = Paint()
..color = Colors.red // Màu của kim giây
..style = PaintingStyle.stroke // Kiểu vẽ là nét kẻ
..strokeCap = StrokeCap.round // Kiểu đầu của kim giây
..strokeWidth = 5; // Độ dày của kim giây
final secondAngle = (time.second - 15) * 6 * (pi / 180); // Tính
góc của kim giây
canvas.drawLine(
center,
center +
Offset(
cos(secondAngle) * radius * 0.9, sin(secondAngle) *
radius * 0.9),
secondPaint,
);

// Vẽ chấm giữa đồng hồ


final centerDotPaint = Paint()
..color = Color.fromARGB(255, 255, 40, 216) // Màu của chấm giữa
đồng hồ
..style = PaintingStyle.fill; // Kiểu vẽ là toàn phần

canvas.drawCircle(center, 15, centerDotPaint); // Vẽ chấm giữa


đồng hồ
}

// Hàm lấy tên của ngày trong tuần


String _getDayOfWeek() {
final weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
"Sat"]; // Tên của các ngày trong tuần
return weekdays[time.weekday - 1]; // Trả về tên của ngày trong
tuần hiện tại
}

// Hàm định dạng số thành dạng có 2 chữ số


String _formatTwoDigits(int value) {
return value.toString().padLeft(2, '0'); // Định dạng số có 2 chữ
số
}

17
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}

18
Bài 4: Chương trình quản lý kho sử dụng
QR/BARCODE
Code
import 'package:flutter/material.dart'; // Import thư viện flutter
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
// Import thư viện flutter_barcode_scanner

void main() {
runApp(MyApp()); // Khởi chạy ứng dụng MyApp
}

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, // Ẩn biểu tượng "debug" trên
banner
home: HomePage(), // Trang chính của ứng dụng là HomePage
);
}
}

class HomePage extends StatefulWidget {


@override
_HomePageState createState() => _HomePageState(); // Trạng thái của
trang chính là _HomePageState
}

class _HomePageState extends State<HomePage> {


// Cập nhật cấu trúc dữ liệu sản phẩm
List<Product> products = [
Product(name: "Bút", quantity: 9, price: 15000, ma: 'LK_04697',
time: DateTime.utc(2024, 2, 25)),
Product(name: "Vở", quantity: 20, price: 15000, ma: 'LK_04666',
time: DateTime.utc(2024, 2, 29)),
Product(name: "Chai Nước", quantity: 5, price: 10000, ma:
'8934588063053', time: DateTime.utc(2024, 3, 3)),
// Thêm các sản phẩm khác theo cùng cấu trúc này
];
bool isNhapsPressed = false; // Trạng thái của nút Nhập hàng
bool isXuatsPressed = false; // Trạng thái của nút Xuất hàng

19
// Hàm quét mã QR
Future<void> scanQRCode() async {
try {
final qrCode = await FlutterBarcodeScanner.scanBarcode(
"#ff6666", "Cancel", true, ScanMode.QR); // Quét mã QR

if (!mounted) return;
int temp = 0;
for (var product in products) {
if (product.ma == qrCode) {
temp = 1;
if (isNhapsPressed) {
product.quantity += 1;
product.time = DateTime.now();
}
if (isXuatsPressed) {
product.quantity -= 1;
product.time = DateTime.now();
}
}
}

if (qrCode == 'LK_04697') {
setState(() {
// Tìm sản phẩm bút trong danh sách và tăng số lượng lên 1
int index = products.indexWhere((product) => product.name ==
"Bút");
if (index != -1) {
// Tăng số lượng sản phẩm bút lên 1
if (isNhapsPressed) {
products[0].quantity += 0;
products[0].time = DateTime.now();
}
if (isXuatsPressed) {
products[0].quantity -= 0;
products[0].time = DateTime.now();
}
} else {
// Nếu không tìm thấy sản phẩm bút, có thể thêm mới hoặc
bỏ qua
// Ví dụ: thêm sản phẩm bút mới với số lượng 1 nếu chưa có
products.add(
Product(name: "Bút", quantity: 1, price: 5000, ma:
'LK_04697', time: DateTime.utc(2024, 3, 3)));
}
});

20
} else if (qrCode == '8934588063053') {
setState(() {
// Tìm sản phẩm bút trong danh sách và tăng số lượng lên 1
int index =
products.indexWhere((product) => product.name == "Chai
Nước");
if (index != -1) {
// Tăng số lượng sản phẩm bút lên 1
products[1].quantity += 0;
} else {
// Nếu không tìm thấy sản phẩm bút, có thể thêm mới hoặc
bỏ qua
// Ví dụ: thêm sản phẩm bút mới với số lượng 1 nếu chưa có
products.add(Product(
name: "Bút", quantity: 1, price: 5000, ma:
'8934588063053', time: DateTime.utc(2024, 3, 3)));
}
});
} else {
if(temp == 0){
_showAddProductDialog(qrCode); // Hiển thị hộp thoại thêm
sản phẩm mới
}
setState(() {});
}
} catch (e) {
// Xử lý lỗi
}
}

// Hàm hiển thị hộp thoại thêm sản phẩm mới


void _showAddProductDialog(String qrCode) {
TextEditingController nameController = TextEditingController();
TextEditingController priceController = TextEditingController();

showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Thêm Sản Phẩm Mới"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: nameController,

21
decoration: InputDecoration(labelText: "Tên Sản
Phẩm"),
),
TextField(
controller: priceController,
decoration: InputDecoration(labelText: "Giá Tiền"),
keyboardType: TextInputType.number,
),
],
),
actions: <Widget>[
TextButton(
child: Text("Thêm"),
onPressed: () {
setState(() {
products.add(Product(
name: nameController.text,
quantity: 1,
price: int.tryParse(priceController.text) ?? 0,
ma: qrCode,
time: DateTime.now()));
});
Navigator.of(context).pop();
},
),
],
);
},
);
}

// Hàm định dạng ngày tháng


String _formattedDateTime(DateTime dateTime) {
return "${dateTime.day}/${dateTime.month}/${dateTime.year}";
}

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 242, 206, 236), // Màu nền
của ứng dụng
appBar: AppBar(
title: Text('Mai Đông Thức - Mã Quang Lộc'), // Tiêu đề của
ứng dụng
backgroundColor: Color.fromARGB(173, 216, 230, 0), // Màu nền
của thanh tiêu đề

22
),

body: Container(
margin: EdgeInsets.all(10), // Thêm margin xung quanh bảng
padding: EdgeInsets.all(10), // Thêm padding bên trong khung
decoration: BoxDecoration(
color: Color.fromARGB(255, 184, 175, 175), // Màu nền của
khung
borderRadius: BorderRadius.circular(10), // Bo góc cho khung
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5), // Màu bóng
spreadRadius: 5, // Độ rộng bóng
blurRadius: 7, // Độ mờ bóng
offset: Offset(0, 3), // Vị trí bóng
),
],
),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
headingRowColor:
MaterialStateProperty.all(Color.fromARGB(255, 232, 162, 96)), // Màu
dòng tiêu đề
dataRowColor:
MaterialStateProperty.all(Color.fromARGB(255, 166, 227, 255),), // Màu
dòng dữ liệu
columns: [
DataColumn(label: Text('Tên')), // Cột Tên sản phẩm
DataColumn(label: Text('SL')), // Cột Số lượng
DataColumn(label: Text('Giá Thành')), // Cột Giá thành
DataColumn(label: Text('Mã Sản Phẩm')), // Cột Mã sản
phẩm
DataColumn(label: Text('Thời Gian')), // Cột Thời gian
],
rows: products
.map((product) => DataRow(cells: [
DataCell(Text(product.name)), // Ô dữ liệu Tên
sản phẩm
DataCell(Text('${product.quantity}')), // Ô dữ
liệu Số lượng
DataCell(Text('${product.price} VND')), // Ô dữ
liệu Giá thành
DataCell(Text('${product.ma}')), // Ô dữ liệu Mã
sản phẩm

23
DataCell(Text('$
{_formattedDateTime(product.time)}')), // Ô dữ liệu Thời gian
]))
.toList(),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => scanQRCode(), // Xử lý sự kiện nhấn nút quét
mã QR
child: Icon(Icons.camera_alt), // Icon của nút
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(), // Hình dạng của thanh dưới
notchMargin: 6.0, // Khoảng cách từ mép đến lỗ
color: const Color.fromARGB(250, 216, 230, 0), // Màu nền của
thanh dưới
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.download,
color: isNhapsPressed ? Colors.red : Colors.blue),
// Icon nút Nhập hàng
onPressed: () {
setState(() {
isNhapsPressed = true; // Đặt trạng thái nút Nhập
hàng
isXuatsPressed = false; // Đặt trạng thái nút Xuất
hàng
// Logic cho hành động nhập hàng
});
},
),
IconButton(
icon: Icon(Icons.upload,
color: isXuatsPressed ? Colors.red : Colors.blue),
// Icon nút Xuất hàng
onPressed: () {
setState(() {
isXuatsPressed = true; // Đặt trạng thái nút Xuất
hàng

24
isNhapsPressed = false; // Đặt trạng thái nút Nhập
hàng
// Logic cho hành động xuất hàng
});
},
),
],
),
),
);
}
}

// Lớp mô tả sản phẩm


class Product {
final String name; // Tên sản phẩm
int quantity; // Số lượng sản phẩm
final int price; // Giá sản phẩm
String ma; // Mã sản phẩm
DateTime time; // Thời gian

Product(
{required this.name,
required this.quantity,
required this.price,
required this.ma,
required this.time});
}

25

You might also like