schools.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. 'use strict';
  2. // 校区地图:学校列表(JSON 种子 + 运行时),附带运营数据关联统计。
  3. // 本期只有只读接口;新建/编辑/启停在下一增量实现。
  4. const { sendJson } = require('../util.js');
  5. const { loadSchools } = require('../../schools-store.js');
  6. const { createOpsStore } = require('../../ops-store.js');
  7. function namesOf(school) {
  8. return new Set([school.name, ...(school.aliases || [])].map((n) => String(n).trim()).filter(Boolean));
  9. }
  10. function register(app, ctx) {
  11. const opsStore = createOpsStore(ctx.config);
  12. app.get('/api/schools', async ({ res }) => {
  13. const schools = loadSchools();
  14. // 关联运营数据:按学校名(含别名)匹配 ops_shop.school 与 ops_row.school
  15. let shops = [];
  16. let rows = [];
  17. let opsAvailable = false;
  18. try {
  19. const summary = await opsStore.summary();
  20. shops = summary.shops || [];
  21. rows = await opsStore.queryRows({});
  22. opsAvailable = true;
  23. } catch { /* ops 库不可用:只影响关联字段 */ }
  24. const payload = schools.map((school) => {
  25. const names = namesOf(school);
  26. const shopCount = shops.filter((s) => names.has(String(s.school || ''))).length;
  27. let lastDate = '';
  28. for (const row of rows) {
  29. if (!names.has(String(row.school || ''))) continue;
  30. if (!lastDate || row.date > lastDate) lastDate = row.date;
  31. }
  32. return {
  33. ...school,
  34. ops: opsAvailable ? { shopCount, lastDate: lastDate || null } : null,
  35. };
  36. });
  37. sendJson(res, 200, {
  38. schools: payload,
  39. opsAvailable,
  40. enabledCount: payload.filter((s) => s.enabled && s.lng != null).length,
  41. });
  42. });
  43. }
  44. module.exports = { register };