Додане повідомлення про оновлення застосунку Оновлен Service Worker Перероблен WebSocket APІ
293 lines
11 KiB
JavaScript
293 lines
11 KiB
JavaScript
const crypto = require('crypto');
|
||
const db = require("../config/db");
|
||
|
||
class StandService {
|
||
getStand(id) {
|
||
return new Promise((res, rej) => {
|
||
const sql = `SELECT * FROM stand_list WHERE id = ?`;
|
||
|
||
db.get(sql, [id], (err, row) => {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
}
|
||
if (!row) {
|
||
console.log({ error: "id not found" });
|
||
return res(false);
|
||
}
|
||
|
||
|
||
let data = {
|
||
"id": Number(row.id),
|
||
"title": row.title,
|
||
"geo": JSON.parse(row.geo),
|
||
"hour_start": Number(row.hour_start),
|
||
"hour_end": Number(row.hour_end),
|
||
"quantity_sheep": Number(row.quantity_sheep),
|
||
"week_days": JSON.parse(row.week_days),
|
||
"processing_time": Number(row.processing_time),
|
||
"status": row.status == 1 ? true : false,
|
||
"updated_at": Number(row.updated_at)
|
||
}
|
||
|
||
return res(data);
|
||
});
|
||
});
|
||
}
|
||
|
||
getList() {
|
||
return new Promise((res, rej) => {
|
||
const sql = `
|
||
SELECT
|
||
*
|
||
FROM
|
||
stand_list
|
||
ORDER BY
|
||
id
|
||
`;
|
||
|
||
db.all(sql, (err, rows) => {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
} else {
|
||
let data = rows.map((row) => {
|
||
return {
|
||
"id": Number(row.id),
|
||
"title": row.title,
|
||
"geo": JSON.parse(row.geo),
|
||
"hour_start": Number(row.hour_start),
|
||
"hour_end": Number(row.hour_end),
|
||
"quantity_sheep": Number(row.quantity_sheep),
|
||
"week_days": JSON.parse(row.week_days),
|
||
"processing_time": Number(row.processing_time),
|
||
"status": row.status == 1 ? true : false,
|
||
"updated_at": Number(row.updated_at)
|
||
}
|
||
})
|
||
|
||
return res(data);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
createStand(data) {
|
||
return new Promise((res, rej) => {
|
||
let sql = 'INSERT INTO stand_list(title, geo, hour_start, hour_end, quantity_sheep, week_days, processing_time, status, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||
|
||
db.run(sql, [
|
||
data.title,
|
||
JSON.stringify(data.geo || []),
|
||
Number(data.hour_start) || 9,
|
||
Number(data.hour_end) || 18,
|
||
Number(data.quantity_sheep) || 2,
|
||
JSON.stringify(data.week_days || [1]),
|
||
Number(data.processing_time) || 1,
|
||
1,
|
||
Math.floor(Date.now())
|
||
], function (err) {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
} else {
|
||
res({ "status": "ok", "id": this.lastID });
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
updateStand(stand_id, data) {
|
||
return new Promise((res, rej) => {
|
||
const sql = `
|
||
UPDATE stand_list SET
|
||
title = COALESCE(?, title),
|
||
geo = COALESCE(?, geo),
|
||
hour_start = COALESCE(?, hour_start),
|
||
hour_end = COALESCE(?, hour_end),
|
||
quantity_sheep = COALESCE(?, quantity_sheep),
|
||
week_days = COALESCE(?, week_days),
|
||
status = COALESCE(?, status),
|
||
updated_at = ?
|
||
WHERE id = ?
|
||
`;
|
||
|
||
db.run(sql, [
|
||
data.title ?? null,
|
||
data.geo !== undefined ? JSON.stringify(data.geo) : null,
|
||
data.hour_start !== undefined ? Number(data.hour_start) : null,
|
||
data.hour_end !== undefined ? Number(data.hour_end) : null,
|
||
data.quantity_sheep !== undefined ? Number(data.quantity_sheep) : null,
|
||
data.week_days !== undefined ? JSON.stringify(data.week_days) : null,
|
||
data.status !== undefined ? (data.status ? 1 : 0) : null,
|
||
Date.now(),
|
||
stand_id
|
||
], function (err) {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
} else if (this.changes === 0) {
|
||
return res(false);
|
||
} else {
|
||
res({ status: "ok", id: stand_id });
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
deleteStand(stand_id) {
|
||
return new Promise((res, rej) => {
|
||
db.run('DELETE FROM stand_list WHERE id = ?', [stand_id], function (err) {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
} else if (this.changes === 0) {
|
||
return res(false);
|
||
} else {
|
||
res({ "status": "ok", "id": stand_id });
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
createSchedule(stand_id) {
|
||
return new Promise((res, rej) => {
|
||
let date_start;
|
||
let getNextMonday = (ts) => {
|
||
let date = new Date(ts);
|
||
// следующий день после max_date
|
||
date.setDate(date.getDate() + 1);
|
||
|
||
// пока не понедельник – добавляем дни
|
||
while (date.getDay() !== 1) {
|
||
date.setDate(date.getDate() + 1);
|
||
}
|
||
return date.getTime();
|
||
}
|
||
|
||
// 1. Получаем стенд
|
||
db.get(`SELECT * FROM stand_list WHERE id = ?`, [stand_id], (err, stand) => {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
}
|
||
if (!stand) {
|
||
console.log({ error: "id not found" });
|
||
return res(false);
|
||
}
|
||
|
||
stand.geo = JSON.parse(stand.geo);
|
||
stand.week_days = JSON.parse(stand.week_days)
|
||
|
||
// 2. Берём последний date из расписания
|
||
db.get(
|
||
`SELECT MAX(date) AS max_date FROM stand_schedule WHERE stand_id = ?`,
|
||
[stand.id],
|
||
(err, row) => {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
}
|
||
|
||
if (row && row.max_date) {
|
||
date_start = getNextMonday(row.max_date); // заменить начальную дату
|
||
} else {
|
||
date_start = getNextMonday(Date.now()); // заменить начальную дату
|
||
}
|
||
|
||
// 3. Генерация новых записей
|
||
const stand_length = (stand.hour_end - stand.hour_start) / stand.processing_time;
|
||
const timestamp = Math.floor(Date.now());
|
||
const list = [];
|
||
|
||
for (const dayOffset of stand.week_days) {
|
||
const stand_date = date_start + (dayOffset * 24 * 60 * 60 * 1000);
|
||
|
||
for (let i = 0; i < stand_length; i++) {
|
||
for (let q = 0; q < stand.quantity_sheep; q++) {
|
||
list.push([
|
||
stand.hour_start + (stand.processing_time * i),
|
||
q,
|
||
stand_date,
|
||
stand.id,
|
||
timestamp
|
||
]);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (list.length === 0) {
|
||
return res({ status: "empty" });
|
||
}
|
||
|
||
// 4. Массовая вставка
|
||
const placeholders = list.map(() => "(?, ?, ?, ?, ?)").join(",");
|
||
const values = list.flat();
|
||
const insertSQL = `
|
||
INSERT INTO stand_schedule(hour, number_sheep, date, stand_id, updated_at)
|
||
VALUES ${placeholders}
|
||
`;
|
||
|
||
db.run(insertSQL, values, function (err) {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
}
|
||
res({ status: "ok", inserted: list.length});
|
||
});
|
||
}
|
||
);
|
||
});
|
||
});
|
||
}
|
||
|
||
getScheduleList(stand_id) {
|
||
return new Promise((res, rej) => {
|
||
const sql = `
|
||
SELECT
|
||
ss.*,
|
||
s.name AS sheep_name
|
||
FROM
|
||
stand_schedule AS ss
|
||
LEFT JOIN
|
||
sheeps AS s
|
||
ON
|
||
s.id = ss.sheep_id
|
||
WHERE
|
||
ss.stand_id = ?
|
||
ORDER BY
|
||
ss.id;
|
||
`;
|
||
|
||
db.all(sql, [stand_id], (err, rows) => {
|
||
if (err) {
|
||
console.error(err.message);
|
||
return res(false);
|
||
} else {
|
||
let data = rows.map((row) => {
|
||
return {
|
||
"id": Number(row.id),
|
||
"stand_id": Number(row.stand_id),
|
||
"date": Number(row.date),
|
||
"hour": Number(row.hour),
|
||
"sheep_id": Number(row.sheep_id),
|
||
"sheep_name": row.sheep_name,
|
||
"number_sheep": Number(row.number_sheep),
|
||
"updated_at": Number(row.updated_at)
|
||
}
|
||
})
|
||
|
||
return res(data);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
getScheduleHistory(id) {
|
||
return new Promise((res, rej) => {
|
||
return res({ id });
|
||
});
|
||
}
|
||
}
|
||
|
||
module.exports = new StandService(); |