Compare commits
2 Commits
feature/im
...
feature/ma
| Author | SHA1 | Date | |
|---|---|---|---|
| 566bce4663 | |||
| c828718498 |
@@ -1,13 +1,24 @@
|
|||||||
const router = require('express').Router()
|
const router = require("express").Router();
|
||||||
const {MasterModel} = require('./model/master')
|
const { MasterModel } = require("./model/master");
|
||||||
const mongoose = require("mongoose")
|
const mongoose = require("mongoose");
|
||||||
const {OrderModel} = require("./model/order")
|
const { OrderModel } = require("./model/order");
|
||||||
|
|
||||||
|
|
||||||
router.get("/masters", async (req, res, next) => {
|
router.get("/masters", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const masters = await MasterModel.find({});
|
const masters = await MasterModel.find({});
|
||||||
const orders = await OrderModel.find({});
|
|
||||||
|
// Создаем объекты для начала и конца текущего дня
|
||||||
|
const today = new Date();
|
||||||
|
today.setHours(0, 0, 0, 0);
|
||||||
|
const tomorrow = new Date(today);
|
||||||
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||||
|
|
||||||
|
const orders = await OrderModel.find({
|
||||||
|
startWashTime: {
|
||||||
|
$gte: today,
|
||||||
|
$lt: tomorrow,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const mastersWithOrders = masters.map((master) => {
|
const mastersWithOrders = masters.map((master) => {
|
||||||
const masterOrders = orders.filter((order) => {
|
const masterOrders = orders.filter((order) => {
|
||||||
@@ -36,11 +47,11 @@ router.get("/masters", async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.delete('/masters/:id', async (req, res,next) => {
|
router.delete("/masters/:id", async (req, res, next) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
|
||||||
if (!mongoose.Types.ObjectId.isValid(id)){
|
if (!mongoose.Types.ObjectId.isValid(id)) {
|
||||||
throw new Error('ID is required')
|
throw new Error("ID is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -48,58 +59,52 @@ router.delete('/masters/:id', async (req, res,next) => {
|
|||||||
new: true,
|
new: true,
|
||||||
});
|
});
|
||||||
if (!master) {
|
if (!master) {
|
||||||
throw new Error('master not found')
|
throw new Error("master not found");
|
||||||
}
|
}
|
||||||
res.status(200).send({success: true, body: master})
|
res.status(200).send({ success: true, body: master });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error)
|
next(error);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
router.post("/masters", async (req, res, next) => {
|
||||||
|
const { name, phone } = req.body;
|
||||||
|
|
||||||
router.post('/masters', async (req, res,next) => {
|
if (!name || !phone) {
|
||||||
|
throw new Error("Enter name and phone");
|
||||||
const {name, phone} = req.body
|
|
||||||
|
|
||||||
if (!name || !phone ){
|
|
||||||
throw new Error('Enter name and phone')
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const master = await MasterModel.create({name, phone})
|
const master = await MasterModel.create({ name, phone });
|
||||||
res.status(200).send({success: true, body: master})
|
res.status(200).send({ success: true, body: master });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error)
|
next(error);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
router.patch("/masters/:id", async (req, res, next) => {
|
||||||
router.patch('/masters/:id', async (req, res, next) => {
|
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
|
||||||
if (!mongoose.Types.ObjectId.isValid(id)) {
|
if (!mongoose.Types.ObjectId.isValid(id)) {
|
||||||
throw new Error('ID is required')
|
throw new Error("ID is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
const { name, phone } = req.body;
|
const { name, phone } = req.body;
|
||||||
|
|
||||||
if (!name && !phone) {
|
if (!name && !phone) {
|
||||||
throw new Error('Enter name and phone')
|
throw new Error("Enter name and phone");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const updateData = {};
|
const updateData = {};
|
||||||
if (name) updateData.name = name;
|
if (name) updateData.name = name;
|
||||||
if (phone) updateData.phone = phone;
|
if (phone) updateData.phone = phone;
|
||||||
|
|
||||||
const master = await MasterModel.findByIdAndUpdate(
|
const master = await MasterModel.findByIdAndUpdate(id, updateData, {
|
||||||
id,
|
new: true,
|
||||||
updateData,
|
});
|
||||||
{ new: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!master) {
|
if (!master) {
|
||||||
throw new Error('master not found')
|
throw new Error("master not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).send({ success: true, body: master });
|
res.status(200).send({ success: true, body: master });
|
||||||
@@ -108,4 +113,4 @@ router.patch('/masters/:id', async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router;
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
const getGigaToken = async () => {
|
|
||||||
const response = await fetch('https://admin.bro-js.ru/api/config/v1/dev')
|
|
||||||
const data = await response.json()
|
|
||||||
return data.features['dry-wash-bh'].GIGA_TOKEN.value
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getGigaToken
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
const { Schema, model } = require('mongoose')
|
const { Schema, model } = require('mongoose')
|
||||||
|
|
||||||
const schema = new Schema({
|
const schema = new Schema({
|
||||||
image: String,
|
file: String,
|
||||||
imageRating: String,
|
|
||||||
imageDescription: String,
|
|
||||||
orderId: {
|
orderId: {
|
||||||
type: Schema.Types.ObjectId,
|
type: Schema.Types.ObjectId,
|
||||||
ref: 'dry-wash-order'
|
ref: 'dry-wash-order'
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ const { MasterModel } = require('./model/master')
|
|||||||
const { OrderModel } = require('./model/order')
|
const { OrderModel } = require('./model/order')
|
||||||
const { OrderCarImgModel } = require('./model/order.car-img')
|
const { OrderCarImgModel } = require('./model/order.car-img')
|
||||||
const { orderStatus } = require('./model/const')
|
const { orderStatus } = require('./model/const')
|
||||||
const { getGigaToken } = require('./get-token')
|
|
||||||
|
|
||||||
const isValidPhoneNumber = (value) => /^(\+)?\d{9,15}/.test(value)
|
const isValidPhoneNumber = (value) => /^(\+)?\d{9,15}/.test(value)
|
||||||
const isValidCarNumber = (value) => /^[авекмнорстух][0-9]{3}[авекмнорстух]{2}[0-9]{2,3}$/i.test(value)
|
const isValidCarNumber = (value) => /^[авекмнорстух][0-9]{3}[авекмнорстух]{2}[0-9]{2,3}$/i.test(value)
|
||||||
@@ -274,124 +273,11 @@ const upload = multer({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const { v4: uuidv4 } = require("uuid")
|
|
||||||
const axios = require('axios')
|
|
||||||
|
|
||||||
const GIGA_CHAT_ACCESS_TOKEN = 'MTQwMmNmZjgtZjA5OC00OGMxLWI0OTUtNWU3ZTU4YzMzZjdjOmU5OGFiYmNiLThmMDItNGVmOC1hNjhhLTA4Y2QxYjVmOGRmMA=='
|
|
||||||
const GIGA_CHAT_OAUTH = 'https://ngw.devices.sberbank.ru:9443/api/v2/oauth'
|
|
||||||
const GIGA_CHAT_API = 'https://gigachat.devices.sberbank.ru/api/v1'
|
|
||||||
|
|
||||||
const getToken = async (req, res) => {
|
|
||||||
const gigaToken = await getGigaToken()
|
|
||||||
|
|
||||||
const rqUID = uuidv4()
|
|
||||||
const body = new URLSearchParams({
|
|
||||||
scope: "GIGACHAT_API_PERS",
|
|
||||||
})
|
|
||||||
|
|
||||||
const response = await fetch(GIGA_CHAT_OAUTH, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
Authorization: `Basic ${gigaToken}`,
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
|
||||||
Accept: "application/json",
|
|
||||||
RqUID: rqUID,
|
|
||||||
},
|
|
||||||
body,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
const errorData = await response.json()
|
|
||||||
console.error("Ошибка запроса: ", errorData)
|
|
||||||
return res.status(response.status).json(errorData)
|
|
||||||
}
|
|
||||||
|
|
||||||
return await response.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
const uploadImage = async (file, accessToken) => {
|
|
||||||
const formData = new FormData()
|
|
||||||
const blob = new Blob([file.buffer], { type: file.mimetype })
|
|
||||||
formData.append('file', blob, file.originalname)
|
|
||||||
formData.append('purpose', 'general')
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
maxBodyLength: Infinity,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Authorization': `Bearer ${accessToken}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await axios.post(`${GIGA_CHAT_API}/files`, formData, config)
|
|
||||||
return response.data.id
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const analyzeImage = async (fileId, token) => {
|
|
||||||
const response = await fetch(`${GIGA_CHAT_API}/chat/completions`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Accept: "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
model: "GigaChat-Max",
|
|
||||||
stream: false,
|
|
||||||
update_interval: 0,
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
role: "system",
|
|
||||||
content:
|
|
||||||
`Ты эксперт по оценке степени загрязнения автомобилей. Твоя задача — анализировать фотографии машин и определять степень их загрязнения.
|
|
||||||
ВАЖНО: Твой ответ ДОЛЖЕН быть СТРОГО в формате JSON и содержать ТОЛЬКО следующие поля:
|
|
||||||
{
|
|
||||||
"value": число от 0 до 10 (целое или с одним знаком после запятой),
|
|
||||||
"description": "текстовое описание на русском языке"
|
|
||||||
}
|
|
||||||
Правила:
|
|
||||||
1. Поле "value":
|
|
||||||
- Должно быть числом от 0 до 10
|
|
||||||
- 0 = машина абсолютно чистая
|
|
||||||
- 10 = машина максимально грязная
|
|
||||||
2. Поле "description":
|
|
||||||
- Должно содержать 2-3 предложения на русском языке
|
|
||||||
- Обязательно указать конкретные признаки загрязнения
|
|
||||||
- Объяснить почему выставлен именно такой балл
|
|
||||||
НЕ ДОБАВЛЯЙ никаких дополнительных полей или комментариев вне JSON структуры.
|
|
||||||
НЕ ИСПОЛЬЗУЙ markdown форматирование.
|
|
||||||
ОТВЕТ ДОЛЖЕН БЫТЬ ВАЛИДНЫМ JSON.`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "user",
|
|
||||||
content: 'Дай оценку для приложенного файла изображения согласно структуре, ответ должен быть на русском языке',
|
|
||||||
attachments: [fileId],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = await response.json()
|
|
||||||
try {
|
|
||||||
return JSON.parse(data.choices[0].message.content)
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
return { description: data.choices[0].message.content }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const convertFileToBase64 = (file) => {
|
const convertFileToBase64 = (file) => {
|
||||||
const base64Image = file.buffer.toString('base64')
|
const base64Image = file.buffer.toString('base64')
|
||||||
return base64Image
|
return base64Image
|
||||||
}
|
}
|
||||||
|
|
||||||
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
||||||
|
|
||||||
router.post('/:id/upload-car-img', upload.single('file'), async (req, res) => {
|
router.post('/:id/upload-car-img', upload.single('file'), async (req, res) => {
|
||||||
const { id: orderId } = req.params
|
const { id: orderId } = req.params
|
||||||
if (!mongoose.Types.ObjectId.isValid(orderId)) {
|
if (!mongoose.Types.ObjectId.isValid(orderId)) {
|
||||||
@@ -406,24 +292,13 @@ router.post('/:id/upload-car-img', upload.single('file'), async (req, res) => {
|
|||||||
throw new Error(VALIDATION_MESSAGES.carImg.required)
|
throw new Error(VALIDATION_MESSAGES.carImg.required)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
const { access_token } = await getToken(req, res)
|
|
||||||
|
|
||||||
const fileId = await uploadImage(req.file, access_token)
|
|
||||||
const { value, description } = await analyzeImage(fileId, access_token) ?? {}
|
|
||||||
|
|
||||||
const orderCarImg = await OrderCarImgModel.create({
|
const orderCarImg = await OrderCarImgModel.create({
|
||||||
image: convertFileToBase64(req.file),
|
file: convertFileToBase64(req.file),
|
||||||
imageRating: value,
|
|
||||||
imageDescription: description,
|
|
||||||
orderId,
|
orderId,
|
||||||
created: new Date().toISOString(),
|
created: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
|
|
||||||
res.status(200).send({ success: true, body: orderCarImg })
|
res.status(200).send({ success: true, body: orderCarImg })
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
router.use((err, req, res, next) => {
|
router.use((err, req, res, next) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user