This commit is contained in:
parent
b88001909f
commit
d571581395
4 changed files with 34 additions and 2 deletions
|
|
@ -64,7 +64,7 @@ let missingCommentsFetchInFlight = false;
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
await loadInternalStatusesConfig(false, true);
|
await loadInternalStatusesConfig(false, true);
|
||||||
await Promise.all([loadMarks(), loadNotes(), loadMentions(), loadUserList(), loadCommentCounts()]);
|
await Promise.all([loadMarks(), loadNotes(), loadMentions(), loadUserList(), loadCommentCounts(), loadClientDict()]);
|
||||||
await loadTasksFromServer();
|
await loadTasksFromServer();
|
||||||
|
|
||||||
if (currentUser.is_admin) {
|
if (currentUser.is_admin) {
|
||||||
|
|
@ -106,6 +106,7 @@ async function loadMarks() { const d = await apiGet('/api/marks'); if (d) marksC
|
||||||
async function loadNotes() { const d = await apiGet('/api/notes'); if (d) notesCache = d; }
|
async function loadNotes() { const d = await apiGet('/api/notes'); if (d) notesCache = d; }
|
||||||
async function loadUserList() { const d = await apiGet('/api/users/list'); if (d) knownUsers = d.map((u) => u.toLowerCase()); }
|
async function loadUserList() { const d = await apiGet('/api/users/list'); if (d) knownUsers = d.map((u) => u.toLowerCase()); }
|
||||||
async function loadCommentCounts() { const d = await apiGet('/api/comments/counts'); if (d && typeof d === 'object') commentCounts = d; }
|
async function loadCommentCounts() { const d = await apiGet('/api/comments/counts'); if (d && typeof d === 'object') commentCounts = d; }
|
||||||
|
async function loadClientDict() { const d = await apiGet('/api/clients'); if (Array.isArray(d)) window._allClients = d; }
|
||||||
|
|
||||||
async function loadTasksFromServer(silent = false) {
|
async function loadTasksFromServer(silent = false) {
|
||||||
if (!silent && !allData.length) showLoading();
|
if (!silent && !allData.length) showLoading();
|
||||||
|
|
|
||||||
|
|
@ -840,8 +840,16 @@ function renderClientUsersCard() {
|
||||||
if (!wrap) return;
|
if (!wrap) return;
|
||||||
|
|
||||||
// createdby — строка с именем создателя, приходит прямо из API
|
// createdby — строка с именем создателя, приходит прямо из API
|
||||||
// Собираем: организация → { total, users: { createdby → count } }
|
// Базовый список клиентов берём из _allClients (все usergroup из dictionaries),
|
||||||
|
// чтобы показывать клиентов с нулём заявок тоже.
|
||||||
const cMap = {};
|
const cMap = {};
|
||||||
|
|
||||||
|
// Сначала заполняем всех известных клиентов с нулями
|
||||||
|
(window._allClients || []).forEach((c) => {
|
||||||
|
cMap[c.name] = { total: 0, users: {} };
|
||||||
|
});
|
||||||
|
|
||||||
|
// Затем считаем реальные заявки
|
||||||
allData.forEach((item) => {
|
allData.forEach((item) => {
|
||||||
const t = item.task;
|
const t = item.task;
|
||||||
const org = t._clientname || t.clientname || 'Неизвестно';
|
const org = t._clientname || t.clientname || 'Неизвестно';
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,12 @@ function createRefreshService({ db, fetch, getSettings, sseBroadcast, logger = c
|
||||||
INSERT OR IGNORE INTO sync_state(id, cache_version, refresh_in_progress)
|
INSERT OR IGNORE INTO sync_state(id, cache_version, refresh_in_progress)
|
||||||
VALUES(1, 0, 0);
|
VALUES(1, 0, 0);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS client_dict (
|
||||||
|
client_id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
updated_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks_index (
|
CREATE TABLE IF NOT EXISTS tasks_index (
|
||||||
task_id TEXT PRIMARY KEY,
|
task_id TEXT PRIMARY KEY,
|
||||||
task_number TEXT NOT NULL,
|
task_number TEXT NOT NULL,
|
||||||
|
|
@ -143,6 +149,10 @@ function createRefreshService({ db, fetch, getSettings, sseBroadcast, logger = c
|
||||||
`),
|
`),
|
||||||
clearIndex: db.prepare('DELETE FROM tasks_index'),
|
clearIndex: db.prepare('DELETE FROM tasks_index'),
|
||||||
insertIndex: db.prepare('INSERT INTO tasks_index(task_id, task_number, updated_at) VALUES(?,?,?)'),
|
insertIndex: db.prepare('INSERT INTO tasks_index(task_id, task_number, updated_at) VALUES(?,?,?)'),
|
||||||
|
upsertClient: db.prepare(`
|
||||||
|
INSERT INTO client_dict(client_id, name, updated_at) VALUES(?,?,?)
|
||||||
|
ON CONFLICT(client_id) DO UPDATE SET name=excluded.name, updated_at=excluded.updated_at
|
||||||
|
`),
|
||||||
upsertIntraStatus: db.prepare(`
|
upsertIntraStatus: db.prepare(`
|
||||||
INSERT INTO intra_status_dict(status_id,name,updated_at) VALUES(?,?,?)
|
INSERT INTO intra_status_dict(status_id,name,updated_at) VALUES(?,?,?)
|
||||||
ON CONFLICT(status_id) DO UPDATE SET name=excluded.name,updated_at=excluded.updated_at
|
ON CONFLICT(status_id) DO UPDATE SET name=excluded.name,updated_at=excluded.updated_at
|
||||||
|
|
@ -452,6 +462,14 @@ function createRefreshService({ db, fetch, getSettings, sseBroadcast, logger = c
|
||||||
const dictMap = {};
|
const dictMap = {};
|
||||||
(json.dictionaries || []).forEach((d) => { dictMap[d.id] = d.name; });
|
(json.dictionaries || []).forEach((d) => { dictMap[d.id] = d.name; });
|
||||||
|
|
||||||
|
// Сохраняем клиентов (usergroup) в отдельную таблицу
|
||||||
|
const now = safeIsoNow();
|
||||||
|
const clientEntries = (json.dictionaries || []).filter((d) => d.type === 'usergroup' && !d.isarchived);
|
||||||
|
const upsertClients = db.transaction((entries) => {
|
||||||
|
for (const d of entries) stmts.upsertClient.run(d.id, d.name, now);
|
||||||
|
});
|
||||||
|
if (clientEntries.length) upsertClients(clientEntries);
|
||||||
|
|
||||||
tasks.forEach((task) => {
|
tasks.forEach((task) => {
|
||||||
if (task.clientid && dictMap[task.clientid]) task._clientname = dictMap[task.clientid];
|
if (task.clientid && dictMap[task.clientid]) task._clientname = dictMap[task.clientid];
|
||||||
if (task.executor && dictMap[task.executor]) task._executorname = dictMap[task.executor];
|
if (task.executor && dictMap[task.executor]) task._executorname = dictMap[task.executor];
|
||||||
|
|
|
||||||
|
|
@ -524,6 +524,11 @@ app.get('/api/status', auth, (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// ── Tasks ─────────────────────────────────────────────────────────
|
// ── Tasks ─────────────────────────────────────────────────────────
|
||||||
|
app.get('/api/clients', auth, (req, res) => {
|
||||||
|
const rows = db.prepare('SELECT client_id, name FROM client_dict ORDER BY name ASC').all();
|
||||||
|
res.json(rows);
|
||||||
|
});
|
||||||
|
|
||||||
app.get('/api/tasks', auth, (req, res) => {
|
app.get('/api/tasks', auth, (req, res) => {
|
||||||
const cache = db.prepare('SELECT * FROM tasks_cache WHERE id=1').get();
|
const cache = db.prepare('SELECT * FROM tasks_cache WHERE id=1').get();
|
||||||
const sync = refreshService.getStatusSnapshot();
|
const sync = refreshService.getStatusSnapshot();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue