fix(ui): полный справочник стран и городов как в VPS Tracker
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 5s
quality / changes (push) Successful in 4s
quality / docker-check (push) Skipped
quality / web (push) Successful in 45s
quality / api (push) Successful in 36s
CD / quality (push) Successful in 1m30s
CD / publish (push) Successful in 1m51s
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 5s
quality / changes (push) Successful in 4s
quality / docker-check (push) Skipped
quality / web (push) Successful in 45s
quality / api (push) Successful in 36s
CD / quality (push) Successful in 1m30s
CD / publish (push) Successful in 1m51s
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Vendored
+62
@@ -236,6 +236,7 @@ function updateAppSettings(db, patch) {
|
||||
// src/fleet-repo.ts
|
||||
import { randomUUID } from "crypto";
|
||||
import { and, asc, count, eq as eq2, sql as sql2 } from "drizzle-orm";
|
||||
import { catalogCitiesWithLocCodes } from "@cdnmanager/shared";
|
||||
function now() {
|
||||
return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
||||
}
|
||||
@@ -272,6 +273,65 @@ function getLocation(db, locationId) {
|
||||
if (!row) throw new NotFoundError(`location ${locationId}`);
|
||||
return mapLocation(row);
|
||||
}
|
||||
function ensureCatalogLocations(db) {
|
||||
const existing = db.select().from(locations).all();
|
||||
const byCode = new Map(existing.map((r) => [r.code.toLowerCase(), r]));
|
||||
const byNameCountry = new Map(
|
||||
existing.map((r) => [
|
||||
`${(r.name || "").trim().toLowerCase()}|${(r.country || "").toUpperCase()}`,
|
||||
r
|
||||
])
|
||||
);
|
||||
let inserted = 0;
|
||||
let sortOrder = 100;
|
||||
for (const city of catalogCitiesWithLocCodes()) {
|
||||
const nameKey = `${city.name.trim().toLowerCase()}|${city.countryCode}`;
|
||||
if (byNameCountry.has(nameKey)) continue;
|
||||
if (byCode.has(city.locCode.toLowerCase())) {
|
||||
const alt = `${city.locCode}${city.countryCode.toLowerCase()}`;
|
||||
if (byCode.has(alt) || byNameCountry.has(nameKey)) continue;
|
||||
db.insert(locations).values({
|
||||
id: `loc-${alt}`,
|
||||
code: alt,
|
||||
name: city.name,
|
||||
country: city.countryCode,
|
||||
sort_order: sortOrder++
|
||||
}).run();
|
||||
byCode.set(alt, { id: `loc-${alt}` });
|
||||
byNameCountry.set(nameKey, { id: `loc-${alt}` });
|
||||
inserted += 1;
|
||||
continue;
|
||||
}
|
||||
db.insert(locations).values({
|
||||
id: `loc-${city.locCode}`,
|
||||
code: city.locCode,
|
||||
name: city.name,
|
||||
country: city.countryCode,
|
||||
sort_order: sortOrder++
|
||||
}).run();
|
||||
byCode.set(city.locCode.toLowerCase(), {
|
||||
id: `loc-${city.locCode}`
|
||||
});
|
||||
byNameCountry.set(nameKey, {
|
||||
id: `loc-${city.locCode}`
|
||||
});
|
||||
inserted += 1;
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
function findLocationByCity(db, cityName, countryCode) {
|
||||
const q = cityName.trim().toLowerCase();
|
||||
if (!q) return null;
|
||||
const rows = listLocations(db);
|
||||
const match = rows.find((l) => {
|
||||
if (l.name.trim().toLowerCase() !== q) return false;
|
||||
if (countryCode && l.country && l.country.toUpperCase() !== countryCode.toUpperCase()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return match ?? null;
|
||||
}
|
||||
function listZones(db) {
|
||||
return db.select().from(zones).orderBy(asc(zones.name)).all().map(mapZone);
|
||||
}
|
||||
@@ -645,6 +705,8 @@ export {
|
||||
deleteAlias,
|
||||
deleteNode,
|
||||
deleteZone,
|
||||
ensureCatalogLocations,
|
||||
findLocationByCity,
|
||||
getAlias,
|
||||
getAppSettings,
|
||||
getLocation,
|
||||
|
||||
Reference in New Issue
Block a user