This commit is contained in:
parent
d571581395
commit
8027e92685
4 changed files with 73 additions and 3 deletions
|
|
@ -64,7 +64,7 @@ let missingCommentsFetchInFlight = false;
|
|||
|
||||
async function init() {
|
||||
await loadInternalStatusesConfig(false, true);
|
||||
await Promise.all([loadMarks(), loadNotes(), loadMentions(), loadUserList(), loadCommentCounts(), loadClientDict()]);
|
||||
await Promise.all([loadMarks(), loadNotes(), loadMentions(), loadUserList(), loadCommentCounts(), loadClientDict(), loadClientUsers()]);
|
||||
await loadTasksFromServer();
|
||||
|
||||
if (currentUser.is_admin) {
|
||||
|
|
@ -107,6 +107,7 @@ async function loadNotes() { const d = await apiGet('/api/notes'); if (d) notesC
|
|||
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 loadClientDict() { const d = await apiGet('/api/clients'); if (Array.isArray(d)) window._allClients = d; }
|
||||
async function loadClientUsers() { const d = await apiGet('/api/client-users'); if (d && typeof d === 'object') window._clientUsers = d; }
|
||||
|
||||
async function loadTasksFromServer(silent = false) {
|
||||
if (!silent && !allData.length) showLoading();
|
||||
|
|
|
|||
|
|
@ -843,10 +843,13 @@ function renderClientUsersCard() {
|
|||
// Базовый список клиентов берём из _allClients (все usergroup из dictionaries),
|
||||
// чтобы показывать клиентов с нулём заявок тоже.
|
||||
const cMap = {};
|
||||
const clientUsers = window._clientUsers || {};
|
||||
|
||||
// Сначала заполняем всех известных клиентов с нулями
|
||||
// Сначала заполняем всех известных клиентов с нулями, включая всех пользователей группы
|
||||
(window._allClients || []).forEach((c) => {
|
||||
cMap[c.name] = { total: 0, users: {} };
|
||||
const users = {};
|
||||
(clientUsers[String(c.client_id)] || []).forEach((u) => { users[u] = 0; });
|
||||
cMap[c.name] = { total: 0, users };
|
||||
});
|
||||
|
||||
// Затем считаем реальные заявки
|
||||
|
|
|
|||
|
|
@ -103,6 +103,14 @@ function createRefreshService({ db, fetch, getSettings, sseBroadcast, logger = c
|
|||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS client_users (
|
||||
user_id INTEGER NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
group_id INTEGER NOT NULL,
|
||||
PRIMARY KEY (user_id, group_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_client_users_group ON client_users(group_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tasks_index (
|
||||
task_id TEXT PRIMARY KEY,
|
||||
task_number TEXT NOT NULL,
|
||||
|
|
@ -153,6 +161,8 @@ function createRefreshService({ db, fetch, getSettings, sseBroadcast, logger = c
|
|||
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
|
||||
`),
|
||||
clearClientUsers: db.prepare('DELETE FROM client_users'),
|
||||
upsertClientUser: db.prepare('INSERT OR REPLACE INTO client_users(user_id, name, group_id) VALUES(?,?,?)'),
|
||||
upsertIntraStatus: db.prepare(`
|
||||
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
|
||||
|
|
@ -598,9 +608,45 @@ function createRefreshService({ db, fetch, getSettings, sseBroadcast, logger = c
|
|||
return dayKeyNow !== dayKeyLast;
|
||||
}
|
||||
|
||||
async function syncClientUsers() {
|
||||
const s = getSettings();
|
||||
if (!s.api_key) return;
|
||||
const pageSize = 100;
|
||||
let skip = 0;
|
||||
const allUsers = [];
|
||||
while (true) {
|
||||
const url = `https://apigw.intradesk.ru/settings/odata/v2/Clients?ApiKey=${s.api_key}`
|
||||
+ `&$filter=${encodeURIComponent('(isarchived eq false)')}`
|
||||
+ `&$top=${pageSize}&$skip=${skip}`;
|
||||
const response = await fetch(url, { timeout: 30000 });
|
||||
if (!response.ok) break;
|
||||
const json = await response.json();
|
||||
const users = json.value || [];
|
||||
allUsers.push(...users);
|
||||
if (users.length < pageSize) break;
|
||||
skip += pageSize;
|
||||
}
|
||||
if (!allUsers.length) return;
|
||||
const tx = db.transaction(() => {
|
||||
stmts.clearClientUsers.run();
|
||||
for (const u of allUsers) {
|
||||
const name = String(u.name || '').trim();
|
||||
if (!name || !u.id) continue;
|
||||
for (const g of (u.groups || [])) {
|
||||
if (g.userGroupId) {
|
||||
stmts.upsertClientUser.run(u.id, name, g.userGroupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
tx();
|
||||
logger.log(`[Refresh] syncClientUsers: stored ${allUsers.length} users`);
|
||||
}
|
||||
|
||||
let running = false;
|
||||
let pending = null;
|
||||
let schedulerTimer = null;
|
||||
let lastClientUsersSync = null;
|
||||
|
||||
function jobPriority(type) {
|
||||
if (type === 'full') return 3;
|
||||
|
|
@ -768,6 +814,14 @@ function createRefreshService({ db, fetch, getSettings, sseBroadcast, logger = c
|
|||
if (settings.refresh_mode === 'incremental_scan') {
|
||||
requestIncremental('scheduler_incremental_scan', { wait: false });
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const needUsersSync = !lastClientUsersSync
|
||||
|| (now - lastClientUsersSync) > 24 * 60 * 60 * 1000;
|
||||
if (needUsersSync) {
|
||||
lastClientUsersSync = now;
|
||||
syncClientUsers().catch((e) => logger.error('[Refresh] syncClientUsers error:', e.message));
|
||||
}
|
||||
}
|
||||
|
||||
function startScheduler() {
|
||||
|
|
@ -799,6 +853,7 @@ function createRefreshService({ db, fetch, getSettings, sseBroadcast, logger = c
|
|||
parseWebhookAction,
|
||||
extractWebhookTaskId,
|
||||
updateIntraAdditionalField,
|
||||
syncClientUsers,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
11
server.js
11
server.js
|
|
@ -529,6 +529,17 @@ app.get('/api/clients', auth, (req, res) => {
|
|||
res.json(rows);
|
||||
});
|
||||
|
||||
app.get('/api/client-users', auth, (req, res) => {
|
||||
const rows = db.prepare('SELECT group_id, name FROM client_users ORDER BY name ASC').all();
|
||||
const result = {};
|
||||
for (const row of rows) {
|
||||
const gid = String(row.group_id);
|
||||
if (!result[gid]) result[gid] = [];
|
||||
result[gid].push(row.name);
|
||||
}
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
app.get('/api/tasks', auth, (req, res) => {
|
||||
const cache = db.prepare('SELECT * FROM tasks_cache WHERE id=1').get();
|
||||
const sync = refreshService.getStatusSnapshot();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue