Add reorderMapPoints functionality and update map controller

This commit is contained in:
2025-12-25 19:28:12 +05:00
parent c877ff2014
commit 6ed4ebde44
5 changed files with 167 additions and 31 deletions
+73
View File
@@ -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<string, Array<(typeof allPoints)[0]>>();
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();
+26 -15
View File
@@ -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" }) }),
});
+11 -10
View File
@@ -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 }) => ({
+7 -6
View File
@@ -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");
}
}
+50
View File
@@ -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" });
}
}