feat: add superadmin assets and notifications

This commit is contained in:
2026-01-15 15:28:41 +08:00
parent c683fa5cf3
commit b896d0fa00
22 changed files with 4852 additions and 260 deletions

View File

@@ -0,0 +1,57 @@
import { requestJson } from './apiClient';
function normalizeItems(items) {
if (Array.isArray(items)) return items;
if (items && typeof items === 'object') return [items];
return [];
}
export const AssetService = {
async listAssets({ page, limit, id, tenant_id, tenant_code, tenant_name, user_id, username, type, status, provider, object_key, created_at_from, created_at_to, size_min, size_max, sortField, sortOrder } = {}) {
const iso = (d) => {
if (!d) return undefined;
const date = d instanceof Date ? d : new Date(d);
if (Number.isNaN(date.getTime())) return undefined;
return date.toISOString();
};
const query = {
page,
limit,
id,
tenant_id,
tenant_code,
tenant_name,
user_id,
username,
type,
status,
provider,
object_key,
created_at_from: iso(created_at_from),
created_at_to: iso(created_at_to),
size_min,
size_max
};
if (sortField && sortOrder) {
if (sortOrder === 1) query.asc = sortField;
if (sortOrder === -1) query.desc = sortField;
}
const data = await requestJson('/super/v1/assets', { query });
return {
page: data?.page ?? page ?? 1,
limit: data?.limit ?? limit ?? 10,
total: data?.total ?? 0,
items: normalizeItems(data?.items)
};
},
async getUsage({ tenant_id } = {}) {
const query = { tenant_id };
return requestJson('/super/v1/assets/usage', { query });
},
async deleteAsset(assetID, { force } = {}) {
if (!assetID) throw new Error('assetID is required');
return requestJson(`/super/v1/assets/${assetID}`, { method: 'DELETE', query: { force } });
}
};

View File

@@ -0,0 +1,102 @@
import { requestJson } from './apiClient';
function normalizeItems(items) {
if (Array.isArray(items)) return items;
if (items && typeof items === 'object') return [items];
return [];
}
export const NotificationService = {
async listNotifications({ page, limit, id, tenant_id, tenant_code, tenant_name, user_id, username, type, is_read, keyword, created_at_from, created_at_to, sortField, sortOrder } = {}) {
const iso = (d) => {
if (!d) return undefined;
const date = d instanceof Date ? d : new Date(d);
if (Number.isNaN(date.getTime())) return undefined;
return date.toISOString();
};
const query = {
page,
limit,
id,
tenant_id,
tenant_code,
tenant_name,
user_id,
username,
type,
is_read,
keyword,
created_at_from: iso(created_at_from),
created_at_to: iso(created_at_to)
};
if (sortField && sortOrder) {
if (sortOrder === 1) query.asc = sortField;
if (sortOrder === -1) query.desc = sortField;
}
const data = await requestJson('/super/v1/notifications', { query });
return {
page: data?.page ?? page ?? 1,
limit: data?.limit ?? limit ?? 10,
total: data?.total ?? 0,
items: normalizeItems(data?.items)
};
},
async broadcast({ tenant_id, user_ids, type, title, content } = {}) {
return requestJson('/super/v1/notifications/broadcast', {
method: 'POST',
body: {
tenant_id,
user_ids,
type,
title,
content
}
});
},
async listTemplates({ page, limit, tenant_id, keyword, type, is_active, created_at_from, created_at_to, sortField, sortOrder } = {}) {
const iso = (d) => {
if (!d) return undefined;
const date = d instanceof Date ? d : new Date(d);
if (Number.isNaN(date.getTime())) return undefined;
return date.toISOString();
};
const query = {
page,
limit,
tenant_id,
keyword,
type,
is_active,
created_at_from: iso(created_at_from),
created_at_to: iso(created_at_to)
};
if (sortField && sortOrder) {
if (sortOrder === 1) query.asc = sortField;
if (sortOrder === -1) query.desc = sortField;
}
const data = await requestJson('/super/v1/notifications/templates', { query });
return {
page: data?.page ?? page ?? 1,
limit: data?.limit ?? limit ?? 10,
total: data?.total ?? 0,
items: normalizeItems(data?.items)
};
},
async createTemplate({ tenant_id, name, type, title, content, is_active } = {}) {
return requestJson('/super/v1/notifications/templates', {
method: 'POST',
body: {
tenant_id,
name,
type,
title,
content,
is_active
}
});
}
};