Saya menulis karena untuk ketiga kalinya dalam setahun saya menemukan tugas ini. Setiap kali, semuanya dimulai dengan solusi kreatif yang luar biasa lebih mudah, dan pada akhirnya datang ke sistem yang akan saya bicarakan.
Tujuannya adalah untuk membuat dan memelihara jadwal mingguan, seperti jadwal pelajaran sekolah atau jadwal dokter dan pejabat. Ada satu set slot, setiap slot adalah tempat dalam jadwal mingguan dengan berbagai parameter tambahan, seperti nomor kabinet, nama karyawan. Diperlukan untuk membangun sistem yang fleksibel dengan sejarah penuh yang dapat menyelesaikan masalah seperti: membuat jadwal yang berbeda dari awal musim panas, mengganti guru untuk 3 minggu ke depan, memindahkan jadwal dari Jumat ke Sabtu karena liburan.
Saya akan menulis tentang apa yang biasanya mereka temukan dan bagaimana menyelesaikannya, saya akan menyelesaikan masalah mengecat strip, dan kemudian saya akan memberikan contoh backend sederhana pada node / sekuel dan diakhiri dengan frontend sederhana pada vue / vuex / vuetify / nuxt, di mana Anda dapat menyeret semuanya dengan mouse dan melihat bagaimana cara kerjanya
Kode diposting di
github , digunakan di
sini .

Perubahan granular
Ada slot, entah bagaimana disajikan dalam database. Perlu diedit. Jadi, Anda perlu menggambar beberapa formulir dengan bidang, dan di bawah tombol "simpan". Lagipula, semuanya biasanya diatur seperti itu. Namun, tidak dalam hal ini. Pertimbangkan bentuknya:
Saat menyimpan, semua data slot diperbarui, riwayat hilang. Mari kita coba tambahkan elemen seperti itu:
Lagi oleh. Sebagai contoh, pada tanggal 4 Juni, pada hari Senin, transfer kelas satu hari dari kantor pertama ke kantor kedua dicatat. Kemudian muncul permintaan baru - mulai 28 Mei, pelajaran akan selalu dimulai pukul 20:00 bukannya 19:00. Kami membuka formulir, mengubah waktu, menunjukkan tanggal dari tanggal 28 dan selamanya dan ... semua bidang, bersama dengan nomor kabinet, pergi ke server. Perubahan sementara pada 4 Juni ditimpa. Dengan menggunakan formulir ini, tidak mungkin untuk menentukan bidang mana pada interval mana yang ingin diubah pengguna, karena semua bidang dikirim sama sekali.
Idenya adalah bahwa setiap aturan berubah secara independen dari yang lain dengan intervalnya sendiri. Slot ditentukan oleh satu set parameter satu dimensi, setiap parameter memiliki riwayat perubahan yang ditentukan oleh serangkaian aturan. Setiap aturan berisi nilai, tanggal mulai dan berakhir. Karena ini adalah kalender mingguan, tanggal sudah cukup untuk menunjukkan hingga satu minggu, YYYYWW.

Tampaknya mengedit slot sekarang sangat rumit - untuk mengubah beberapa bidang, Anda perlu memilih setiap bidang, membuka formulir, meletakkan nilai dan interval. Namun, dalam praktiknya, mengubah beberapa bidang terbukti menjadi situasi yang langka. Jauh lebih sering adalah pembaruan massal beberapa slot sekaligus. Misalnya, untuk menghapus ketidakhadiran guru karena sakit, Anda harus memilih semua bloknya, memasukkan status tugas staf dalam cuti medis, dan kemudian memilih guru pengganti untuk blok yang sama. Hanya 2 tindakan dan bukannya n tindakan untuk n slot dalam kasus ini, seolah-olah mereka ditentukan melalui formulir tradisional. Pada sistem
StarBright.com yang sedang saya kerjakan, tampilannya seperti ini:
Tugas melukis strip
Pertimbangkan strip yang terdiri dari sel-sel yang dicat dengan warna berbeda. Setiap sel adalah satu minggu, setiap warna adalah sebuah makna. Warna baru datang dan interval untuk mengaplikasikannya, mereka perlu mengecat ulang apa yang ada. Pada tingkat data, ini berarti bahwa Anda perlu menghapus interval yang tumpang tindih sepenuhnya, mengubah interval tumpang tindih sebagian, menambahkan interval baru, menggabungkan interval satu warna yang berdekatan menjadi satu. Hasil akhir harus terdiri dari interval yang tidak tumpang tindih.
Hasil: [{delete, id: 2}, {update, id: 1, data: {to: 5}}, {update, id: 3, data: {from: 16}}, {insert, data: {from : 6, hingga: 15, nilai: menikah}}]Ini adalah tugas yang sederhana, tetapi mudah untuk mengabaikan sesuatu di sini.
Berikut adalah repositori terpisah dengan solusi dan tes.
http://timeblock-rules.rag.lt - di sini Anda dapat memeriksa cara kerjanya dan bermain dengan shading.
Backend
Aturan tidak tumpang tindih, sehingga `pilih * dari aturan yang paling sederhana dari <=: minggu dan (menjadi nol atau>>: minggu)` sudah cukup untuk memilih dengan tepat aturan yang diperlukan untuk minggu yang ditentukan.
Berikut adalah contoh sederhana backend pada node / sequelize. Ia menggunakan gaya gabungan c janji dan asink / tunggu, yang dapat Anda baca
di artikel saya yang lain .
Berikut adalah tindakan yang memilih aturan untuk minggu yang ditentukan:
routes.get('/timeblocks', async (req, res) => { try { ... validation ... await Rule .findAll({ where: { from: {$or: [{$lte: req.query.week}, null]}, to: {$or: [{$gte: req.query.week}, null]} } }) .then( sendSuccess(res, 'Calendar data extracted.'), throwError(500, 'sequelize error') ) } catch (error) { catchError(res, error) } })
Dan di sini adalah PATCH untuk mengubah aturan:
routes.patch('/timeblocks/:id(\\d+)', async (req, res) => { try { ... validation ... const initialRules = await Rule .findAll({ where: { timeblock_id: req.params.id, type: {$in: req.params.rules.map(rule => rule.type)} } }).catch(throwError(500, 'sequelize error')) const promises = [] req.params.rules.forEach(rule => {
Ini adalah bagian ideologis paling sulit dari backend, sisanya bahkan lebih sederhana.
Pertanyaannya adalah bagaimana cara menghapus slot. Dalam hal ini, riwayat lengkap disimpan, tidak ada yang dihapus. Ada bidang status yang dapat dibuka, sementara ditutup dan ditutup. Pengunjung melihat slot aktif dan untuk sementara tidak aktif, di yang terakhir biasanya admin biasanya menulis komentar tentang mengapa tidak ada aktivitas. Seiring waktu, ada banyak slot tertutup, dan untuk menyederhanakan situasi, ada baiknya untuk memperkenalkan properti lain seperti tahun ajaran dan hanya menampilkan tahun sekolah saat ini saat mengedit slot.
Frontend
Kode dalam
repositori ini , itu adalah situs satu halaman sederhana di nuxt. Sebenarnya, ada beberapa masalah dengan ssr (misalnya,
saya menganalisis secara rinci cara menulis otentikasi pada nuxt), tetapi aplikasi sederhana ditulis dengan sangat cepat.
Berikut adalah kode untuk satu halaman:
export default { components: {...}, fetch ({app, route, redirect, store}) { if (!route.query.week) { const newRoute = app.router.resolve({query: {...route.query, week: moment().format('YYYYWW')}}, route) return redirect(newRoute.href) } return Promise.resolve() .then(() => store.dispatch('calendar/set', {week: route.query.week})) .then(() => store.dispatch('calendar/fetch')) }, computed: { week () { return this.$store.state.calendar.week } }, watch: { week (week) { this.$router.push({ query: { ...this.$route.query, week } }) this.$store.dispatch('calendar/fetch') } } }
Metode pengambilan bekerja di server dan klien, mengalihkan ke minggu ini dan meminta kalender. Ketika minggu berubah, data diminta kembali.
Apa yang harus dilakukan dengan slot yang tumpang tindih? Jawabannya tergantung pada logika bisnis, misalnya, Anda mungkin memerlukan validasi server yang melarang overlay. Dalam hal ini, overlay diperbolehkan, dan untuk mendapatkan gambar yang indah, slot tersebut ditarik setengah lebar di samping satu sama lain. Tambahkan tata letak dan dapatkan tampilan ini:
Yang lainnya adalah javascript biasa tanpa ide khusus. Dengan mousedown di blok, seret dan lepas dimulai. Acara mousemove dan mouseup digantung di seluruh jendela. Seret dan lepas dimulai dengan penundaan 200 ms untuk membedakan seret dari klik. Parameter wadah tempat drop dilacak dihitung terlebih dahulu, karena getBoundingClientRect adalah operasi yang terlalu berat untuk dilakukan untuk setiap gerakan mouse. Saya harus membuat dua bentuk - satu untuk membuat (mengatur semua aturan sekaligus mulai dari minggu ini), yang lain untuk perubahan granular ke slot.
http://calendar.rag.lt - di sini Anda dapat memeriksa cara kerja semuanya.
Tautan ke artikel