diff --git a/order.ts b/order.ts new file mode 100644 index 0000000..82beaba --- /dev/null +++ b/order.ts @@ -0,0 +1,73 @@ +import { db } from "./src/db"; +import { mapTable } from "./src/db/schema"; +import { eq } from "drizzle-orm"; + +async function reorderMapPoints() { + try { + console.log("🚀 Начинаю обработку точек на карте...\n"); + + // Получаем все записи из таблицы map + const allPoints = await db.query.mapTable.findMany({ + orderBy: (mapTable, { asc }) => [asc(mapTable.city), asc(mapTable.id)], + }); + + if (allPoints.length === 0) { + console.log("⚠️ Записей в таблице map не найдено."); + return; + } + + console.log(`📊 Найдено записей: ${allPoints.length}`); + + // Группируем точки по городам + const pointsByCity = new Map>(); + + for (const point of allPoints) { + if (!pointsByCity.has(point.city)) { + pointsByCity.set(point.city, []); + } + pointsByCity.get(point.city)!.push(point); + } + + console.log(`🏙️ Найдено городов: ${pointsByCity.size}\n`); + + // Обновляем order для каждого города + let totalUpdated = 0; + + for (const [city, points] of pointsByCity) { + console.log(`📍 Обрабатываю город: ${city} (${points.length} точек)`); + + // Обновляем каждую точку с новым значением order + const updatePromises = points.map((point, index) => + db + .update(mapTable) + .set({ order: index }) + .where(eq(mapTable.id, point.id)) + ); + + await Promise.all(updatePromises); + + totalUpdated += points.length; + console.log( + ` ✅ Обновлено: ${points.length} точек (order: 0-${ + points.length - 1 + })` + ); + } + + console.log("\n" + "=".repeat(50)); + console.log(`✨ Успешно завершено!`); + console.log(`📊 Статистика:`); + console.log(` - Всего городов: ${pointsByCity.size}`); + console.log(` - Всего обновлено точек: ${totalUpdated}`); + console.log("=".repeat(50)); + + process.exit(0); + } catch (error) { + console.error("\n❌ Ошибка при выполнении скрипта:"); + console.error(error); + process.exit(1); + } +} + +// Запускаем скрипт +reorderMapPoints(); diff --git a/src/controllers/map.ts b/src/controllers/map.ts index 008a5f2..760f8f2 100644 --- a/src/controllers/map.ts +++ b/src/controllers/map.ts @@ -1,20 +1,21 @@ -import { createInsertSchema, createSelectSchema } from 'drizzle-typebox'; -import Elysia, { t } from 'elysia'; -import { mapTable } from '../db/schema'; -import { getByCity } from '../services/map/getByCity'; -import { authMiddleware } from '../middlewares/auth'; -import { createMapPoint } from '../services/map/createMapPoint'; -import { updateMapPoint } from '../services/map/updateMapPoint'; -import { deleteMapPoint } from '../services/map/deleteMapPoint'; +import { createInsertSchema, createSelectSchema } from "drizzle-typebox"; +import Elysia, { t } from "elysia"; +import { mapTable } from "../db/schema"; +import { getByCity } from "../services/map/getByCity"; +import { authMiddleware } from "../middlewares/auth"; +import { createMapPoint } from "../services/map/createMapPoint"; +import { updateMapPoint } from "../services/map/updateMapPoint"; +import { deleteMapPoint } from "../services/map/deleteMapPoint"; +import { reorderMapPoints } from "../services/map/reorderMapPoints"; const getMapPointsSchema = createSelectSchema(mapTable); const createMapPointSchema = createInsertSchema(mapTable); export const mapController = new Elysia({ - prefix: '/map', + prefix: "/map", }) - .get('/', async ({ query: { city } }) => await getByCity(city), { + .get("/", async ({ query: { city } }) => await getByCity(city), { response: { 200: t.Array(getMapPointsSchema), 404: t.ObjectString({}), @@ -25,12 +26,22 @@ export const mapController = new Elysia({ }), }) .use(authMiddleware) - .post('/', async ({ body }) => await createMapPoint(body), { + .post( + "/reorder", + async ({ body: { points, city } }) => await reorderMapPoints(city, points), + { + body: t.Object({ + points: t.Array(t.String({ format: "uuid" })), + city: t.String(), + }), + } + ) + .post("/", async ({ body }) => await createMapPoint(body), { response: { 200: getMapPointsSchema, 500: t.ObjectString({}) }, body: createMapPointSchema, }) .put( - '/:id', + "/:id", async ({ body, params: { id } }) => await updateMapPoint(id, body), { response: { @@ -38,15 +49,15 @@ export const mapController = new Elysia({ 404: t.ObjectString({}), 500: t.ObjectString({}), }, - params: t.Object({ id: t.String({ format: 'uuid' }) }), + params: t.Object({ id: t.String({ format: "uuid" }) }), body: createMapPointSchema, } ) - .delete('/:id', async ({ params: { id } }) => await deleteMapPoint(id), { + .delete("/:id", async ({ params: { id } }) => await deleteMapPoint(id), { response: { 200: getMapPointsSchema, 404: t.ObjectString({}), 500: t.ObjectString({}), }, - params: t.Object({ id: t.String({ format: 'uuid' }) }), + params: t.Object({ id: t.String({ format: "uuid" }) }), }); diff --git a/src/db/schema/map.ts b/src/db/schema/map.ts index e76ef9d..a88ba00 100644 --- a/src/db/schema/map.ts +++ b/src/db/schema/map.ts @@ -1,18 +1,19 @@ -import { pgTable, text, uuid, varchar } from 'drizzle-orm/pg-core'; -import { companiesTable } from './companies'; -import { projectsTable } from './projects'; -import { relations } from 'drizzle-orm'; +import { integer, pgTable, text, uuid, varchar } from "drizzle-orm/pg-core"; +import { companiesTable } from "./companies"; +import { projectsTable } from "./projects"; +import { relations } from "drizzle-orm"; -export const mapTable = pgTable('map', { - id: uuid('id').defaultRandom().primaryKey(), - city: varchar('city', { length: 50 }).notNull(), - src: text('src'), - companyId: uuid('company_id') +export const mapTable = pgTable("map", { + id: uuid("id").defaultRandom().primaryKey(), + city: varchar("city", { length: 50 }).notNull(), + src: text("src"), + companyId: uuid("company_id") .notNull() .references(() => companiesTable.id), - projectId: uuid('project_id') + projectId: uuid("project_id") .notNull() .references(() => projectsTable.id), + order: integer("order"), }); export const mapRelations = relations(mapTable, ({ one }) => ({ diff --git a/src/services/map/getByCity.ts b/src/services/map/getByCity.ts index 0986be4..c4cf343 100644 --- a/src/services/map/getByCity.ts +++ b/src/services/map/getByCity.ts @@ -1,7 +1,7 @@ -import { eq } from 'drizzle-orm'; -import { db } from '../../db'; -import { mapTable } from '../../db/schema'; -import { error } from 'elysia'; +import { eq } from "drizzle-orm"; +import { db } from "../../db"; +import { mapTable } from "../../db/schema"; +import { error } from "elysia"; export async function getByCity(city: string) { try { @@ -11,11 +11,12 @@ export async function getByCity(city: string) { company: true, project: true, }, + orderBy: (mapTable, { asc }) => [asc(mapTable.order)], }); - if (!res) return error(404, { error: 'Map point not found' }); + if (!res) return error(404, { error: "Map point not found" }); return res; } catch (err) { console.log((err as Error).message); - return error(500, 'Internal Server Error'); + return error(500, "Internal Server Error"); } } diff --git a/src/services/map/reorderMapPoints.ts b/src/services/map/reorderMapPoints.ts new file mode 100644 index 0000000..06e6911 --- /dev/null +++ b/src/services/map/reorderMapPoints.ts @@ -0,0 +1,50 @@ +import { eq } from "drizzle-orm"; +import { db } from "../../db"; +import { mapTable } from "../../db/schema"; +import { error } from "elysia"; + +export async function reorderMapPoints(city: string, pointIds: string[]) { + try { + // Проверяем, что все точки существуют и принадлежат указанному городу + const existingPoints = await db.query.mapTable.findMany({ + where: eq(mapTable.city, city), + }); + + // Проверяем, что количество ID совпадает с количеством точек в городе + if (existingPoints.length !== pointIds.length) { + return error(400, { + error: "Number of points doesn't match existing points in the city", + }); + } + + // Проверяем, что все ID существуют + const existingIds = new Set(existingPoints.map((p) => p.id)); + const allIdsExist = pointIds.every((id) => existingIds.has(id)); + + if (!allIdsExist) { + return error(404, { error: "One or more point IDs not found" }); + } + + // Обновляем order для каждой точки согласно новому порядку + const updatePromises = pointIds.map((pointId, index) => + db.update(mapTable).set({ order: index }).where(eq(mapTable.id, pointId)) + ); + + await Promise.all(updatePromises); + + // Возвращаем обновленные точки для данного города + const updatedPoints = await db.query.mapTable.findMany({ + where: eq(mapTable.city, city), + orderBy: (mapTable, { asc }) => [asc(mapTable.order)], + with: { + company: true, + project: true, + }, + }); + + return updatedPoints; + } catch (err) { + console.log((err as Error).message); + return error(500, { error: "Internal Server Error" }); + } +}