Đạo diễn: {this.state.Director}
Biên kịch: {this.state.Writer}
Nhà sản xuất: {this.state.Production}
Quốc gia: {this.state.National}
Ngày rạp: {dateTime && dateTime[0]}
Thời lượng: {this.state.RunningTime} phút
Độ tuổi: {this.state.Rated}
Thể loại:{' '} {this.state.Genres && this.state.Genres.map((genres, keyGenres) => ( 88 {`${String.fromCharCode(160)}${genres}`}, ))}
{this.state.Score && ( -IMDB: {this.state.Score[0].IMDB} RottenTomato: {this.state.Score[0].RottenTomato} )} Component phẩn review phim: const reviewImage = this.props.filmDetail?.ReviewImage; let reviewContent; if (this.props.filmDetail) { reviewContent = { html: marked(this.props.filmDetail?.ReviewContent), }; } return (review :
); Sử dụng CSS để xây dựng giao diện: film-detail actor-title { display: flex; flex-direction: column; align-items: flex-end; padding: 150px; } film-detail actor-title h2 { color: #fff; padding: 5px 10px 30vw; border-bottom: 1px solid #4d4d4d; margin-bottom: 50px; width: 100%; text-align: right; } film-detail film-content { 90 display: flex; width: 100%; justify-content: space-between; padding: 150px; } film-detail film-content film-review { flex-basis: 50%; text-align: left; display: flex; flex-direction: column; justify-content: center; padding: 50px 100px; height: 100vh; overflow: auto; align-items: center; position: relative; border-radius: 10px; } film-detail film-content film-review overlay { position: absolute; top: 0; bottom: 0; right: 0; left: 0; background: rgba(21, 22, 23, 0.55); z-index: 1; border-radius: 10px; } Reducer trang phim chi tiết: const DetailFilmReducer = (state = DEFAULT_STATE, action = {}) => { switch (action.type) { 91 case Constants.GET_FILM_DETAIL_REQUEST: return { state, isFetching: true, }; case Constants.GET_FILM_DETAIL_SUCCESS: return { state, isFetching: false, dataFetched: true, error: false, errorMessage: null, filmDetail: action.payload, }; case Constants.GET_FILM_DETAIL_FAILURE: return { state, isFetching: false, error: true, errorMessage: action.payload, }; default: return state; } }; Xử lý Saga: function* getFilmDetail(action) { try { const dataSend = { 92 path: `/film/${action.payload}`, method: types.GET, }; const result = yield getFilmDetailAPI(dataSend); yield put(actions.getFilmDetailSuccess(result)); } catch (error) { yield put(actions.getFilmDetailFailure(error.message)); } } takeEvery(types.GET_FILM_DETAIL_REQUEST, getFilmDetail), Gọi API file Fetch API: export default function getFilmDetailAPI(data) { const objFetch = { method: data.method }; return new Promise((resolve, reject) => { const url = Constants.DOMAIN + data.path fetch(url, objFetch).then((res) => resolve(res.json())) catch((err) => reject(err)) }) } Một số đoạn code xây dựng Back-end chương Một số API đc tạo file Route: API phim: app.route('/films').get(film_controller.get_film); app route('/film') post(film_controller.add_film) delete(film_controller.delete_film); 93 app.route('/film/live').delete(film_controller.delete_in_theate r_film); app.route('/film/search').get(film_controller.search_film); app route('/film/:film_id') get(film_controller.get_film_by_id) put(film_controller.update_film); app.route('/film/add_hot').post(film_controller.update_hot_film ); app.route('/film/add_new').post(film_controller.update_new_film ); app route('/film/film_image/:film_id') post(film_controller.upload_film_image) put(film_controller.upload_film_image); Xử lý Controller: Thêm phim: exports.add_film = async (req, res) => { req.files.map(async (file) => { if (file.fieldname === 'filmData') { const newFilm = JSON.parse(fs.readFileSync(file.path)); fs.unlinkSync(file.path); console.log(newFilm); const film = await Film.create(newFilm); res.redirect(307, `/film/film_image/${film._id}`); } }); }; 94 Cập nhật phim: exports.update_film = (req, res) => { let updateFilm; const id = req.params.film_id; req.files.map((file) => { if (file.fieldname === 'filmData') { updateFilm = JSON.parse(fs.readFileSync(file.path)); fs.unlinkSync(file.path); } }); Film.findByIdAndUpdate(id, updateFilm, { new: true, useFindAndM odify: false }) then(() => { res.redirect(307, `/film/film_image/${id}`); }) catch((err) => { console.log(err); }); }; Xóa phim: exports.delete_film = (req, res) => { const listId = req.body; const deletePromise = listId.map( (filmId) => new Promise((resolve, reject) => { Film.findByIdAndUpdate(filmId, { isDeleted: true }, { new : true }) then((result) => { 95 resolve(result); }) catch((err) => { reject(err); }); }), ); Promise.all(deletePromise) then((result) => { res.send({ result }); }) catch((err) => { res.send({ err }); }); }; Mô bảng với file Model: Bảng phim var mongoose = require('mongoose'); var Schema = mongoose.Schema; var FilmSchema = new Schema({ FilmName: { type: String, required: [true, 'nhap ten phim'], }, Director: { type: String, }, 96 Writer: { type: String, }, Production: { type: String, }, Actors: [ { type: Schema.Types.ObjectId, ref: 'actor', require: [true, 'Khong co dien vien'], }, ], Cinemas: [ { type: Schema.Types.ObjectId, ref: 'cinemaCluster', require: [true, 'Khong co rap'], }, ], Genres: [ { type: String, require: [true, 'Khong co the loai'], }, ], RunningTime: { type: Number, required: [true, 'Nhap thoi gian phim'], 97 }, ReleaseDate: { type: Date, required: [true, 'nhap mat nao'], }, ReviewContent: { type: String, required: [true, 'Khong co review a ????'], }, Rated: { type: String, }, CoverImage: { type: Schema.Types.ObjectId, ref: 'image', default: null, }, PosterImage: { type: Schema.Types.ObjectId, ref: 'image', require: [true, 'anh dau ???'], }, Images: [ { type: Schema.Types.ObjectId, ref: 'image', default: null, }, ], 98 ReviewImage: { type: Schema.Types.ObjectId, ref: 'image', }, Score: [ { IMDB: { type: String, }, RottenTomato: { type: String, }, }, ], TrailerUrl: { type: String, require, }, National: { type: String, }, isHotFilm: { type: Boolean, default: false, }, isNewFilm: { type: Boolean, default: false, }, 99 isShowing: { type: Boolean, default: true, }, isDeleted: { type: Boolean, default: false, }, }); module.exports = mongoose.model('film', FilmSchema); 100 KẾT LUẬN Kết luận Công nghệ lĩnh vực thay đổi phát triển, công nghệ cập nhật với tính vượt trội Đối với cơng nghệ thơng tin nói riêng, địi hỏi lập trình viên phải ln trau dồi kiến thức mới, tìm phương pháp tối ưu để phù hợn với xu hướng xã hội Chính việc áp dụng mơ hình Web Services Web API với React tảng NodeJS, kết hợp với công nghệ NoSQL – MongoDB xu đánh giá cao nhà phát triển tính mà chúng đem lại Đi đôi với phát triển cơng nghệ phát triển đời sống người Nhu cầu giải trí tăng, rạp chiếu phim trở thành lựa chọn khơng thể thiếu Vì vậy, để người xem có lựa chọn tốt phù hợp với thân, hệ thống giới thiệu phim rạp chiếu phim trở nên cần thiết Để tiếp cận dễ dàng với người dùng bùng nổ Internet tảng web lựa chọn mà em hướng tới Những điểm đạt được: Giao diện bắt mắt, thân thiện với người dùng, chức thể rõ ràng, dễ nắm bắt Xây dựng Front-end React nên việc phân chia Component giúp giao diện trở nên dễ quản lý lập trình viên Đã xây dựng chức Website giới thiệu phim với thông tin cần thiết giúp người dùng có lựa chọn hợp với nhu cầu thân Đối với quản trị viên, chức quản lý phim, rạp danh mục liên quan thuận tiện, dễ sử dụng Những điểm hạn chế: Tuy cố gắng nhận giúp đỡ tận tình giảng viên hướng dẫn, song thời gian, trình độ kinh phí có hạn nên Website mà em xây dựng tồn số hạn chế sau: Chưa có chức để người dùng tương tác, đánh giá bình luận phim Các chức admin tồn hạn chế, chưa thực linh động việc xử lý 101 TÀI LIỆU THAM KHẢO [1] , w3schools.com [2] , nodejs.org [3] , reactjs.org [4] , mongodb.com [5] , cucdienanh.vn [6] , Trần Thị Song Minh (2019), Hệ thống thông tin quản lý – Nhà xuất Đại học Kinh tế quốc dân [7] , Đoàn Văn Ban, Nguyễn Thị Tĩnh (2012), Phân tích thiết kế hướng đối tượng UML, Nhà xuất Đại học Sư phạm [8] , Anthony Accomazzo, Ari Lerner, Nate Murray, Clay Allsopp, David Gutman Tyler McGinnis (2017), Fullstack React The Complete Guide to ReactJS and Friends, Được xuất San Francisco - California Fullstack.io [9] , Tutorials Point (2018), E-book: MongoDB NoSQL Document Database 102