fix(assets): expose full inventory for scoped users and stabilize previews
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -9,7 +9,7 @@ import type {
|
||||
BatchGroup,
|
||||
InventoryTypeSummary,
|
||||
} from '../types.js';
|
||||
import { filterByPermission, maskCustomerNames, maskCustomerName } from '../auth/permissions.js';
|
||||
import { filterAssetVehiclesByPermission, filterByPermission, maskCustomerNames, maskCustomerName } from '../auth/permissions.js';
|
||||
import type { AuthUser } from '../auth/types.js';
|
||||
import type { Context } from 'hono';
|
||||
import {
|
||||
@@ -46,12 +46,12 @@ import {
|
||||
|
||||
export { mapRegion } from './vehicles/model.js';
|
||||
|
||||
const app = new Hono();
|
||||
const app = new Hono<{ Variables: { user: AuthUser } }>();
|
||||
|
||||
async function getVehiclesForUser(c: Context): Promise<Vehicle[]> {
|
||||
async function getVehiclesForUser(c: Context, includePublicInventory = true): Promise<Vehicle[]> {
|
||||
const all = await vehicleRepository.getVehicles();
|
||||
const user = ((c as any).get?.('user') || (c as any).var?.user) as AuthUser | undefined;
|
||||
let list = user ? filterByPermission(all, user) : all;
|
||||
let list = user ? (includePublicInventory ? filterAssetVehiclesByPermission(all, user) : filterByPermission(all, user)) : all;
|
||||
list = applySubjectFilter(c, list);
|
||||
return maskCustomerNames(list);
|
||||
}
|
||||
@@ -71,7 +71,8 @@ function applySubjectFilter(c: Context, vehicles: Vehicle[]): Vehicle[] {
|
||||
// GET /api/vehicles/summary
|
||||
app.get('/summary', async (c) => {
|
||||
const [vehicles, weeklyIds] = await Promise.all([getVehiclesForUser(c), vehicleRepository.getWeeklyTruckIds()]);
|
||||
const vehicleIds = new Set(vehicles.map(v => String(v.id)));
|
||||
const user = c.get('user') as AuthUser | undefined;
|
||||
const vehicleIds = new Set((user ? filterByPermission(vehicles, user) : vehicles).map(v => String(v.id)));
|
||||
const summary: SummaryData = {
|
||||
totalAssets: vehicles.length,
|
||||
operating: {
|
||||
@@ -98,7 +99,15 @@ app.get('/summary', async (c) => {
|
||||
|
||||
// GET /api/vehicles/by-type
|
||||
app.get('/by-type', async (c) => {
|
||||
const [vehicles, weeklyIds] = await Promise.all([getVehiclesForUser(c), vehicleRepository.getWeeklyTruckIds()]);
|
||||
const [vehicles, allWeeklyIds] = await Promise.all([getVehiclesForUser(c), vehicleRepository.getWeeklyTruckIds()]);
|
||||
const user = c.get('user') as AuthUser | undefined;
|
||||
const historyIds = new Set((user ? filterByPermission(vehicles, user) : vehicles).map(v => String(v.id)));
|
||||
const weeklyIds = {
|
||||
...allWeeklyIds,
|
||||
delivered: new Set([...allWeeklyIds.delivered].filter(id => historyIds.has(id))),
|
||||
returned: new Set([...allWeeklyIds.returned].filter(id => historyIds.has(id))),
|
||||
replaced: new Set([...allWeeklyIds.replaced].filter(id => historyIds.has(id))),
|
||||
};
|
||||
|
||||
const result: TypeSummary[] = SUMMARY_TYPE_FILTERS.map((t) => {
|
||||
const typeVehicles = vehicles.filter(t.filter);
|
||||
@@ -587,8 +596,9 @@ app.get('/weekly-detail', async (c) => {
|
||||
const hasModelFilter = model && model !== 'All';
|
||||
const hasBatchFilter = batch && batch !== 'All';
|
||||
const hasLocationFilter = location && location !== 'All';
|
||||
if (hasModelFilter || hasBatchFilter || hasLocationFilter || getSubjectParam(c)) {
|
||||
const vehicles = await getVehiclesForUser(c);
|
||||
{
|
||||
// Public current inventory does not grant access to historical delivery/return events.
|
||||
const vehicles = await getVehiclesForUser(c, type === 'pending');
|
||||
let pool2 = vehicles;
|
||||
if (hasModelFilter) pool2 = pool2.filter((v) => v.model === model);
|
||||
if (hasBatchFilter) pool2 = pool2.filter((v) => (v.contractNo || '未知') === batch);
|
||||
@@ -605,7 +615,7 @@ app.get('/weekly-detail', async (c) => {
|
||||
// 资产流转日报:按运维签章时间统计业务车次;交车包含关联替换单的记录,替换作为其中的子项,同车多笔业务分别累计。
|
||||
app.get('/flow-stats', async (c) => {
|
||||
const { start, end } = normalizeDateRange(c.req.query('start'), c.req.query('end'));
|
||||
const allowedVehicles = await getVehiclesForUser(c);
|
||||
const allowedVehicles = await getVehiclesForUser(c, false);
|
||||
const allowedTruckIds = new Set(allowedVehicles.map((v) => String(v.id)));
|
||||
|
||||
const rows = await vehicleRepository.getFlowDetailRows(start, end);
|
||||
@@ -654,7 +664,7 @@ app.get('/flow-stats', async (c) => {
|
||||
app.get('/subjects', async (c) => {
|
||||
const all = await vehicleRepository.getVehicles();
|
||||
const user = ((c as any).get?.('user') || (c as any).var?.user) as AuthUser | undefined;
|
||||
const visible = user ? filterByPermission(all, user) : all;
|
||||
const visible = user ? filterAssetVehiclesByPermission(all, user) : all;
|
||||
|
||||
const map = new Map<string, { total: number; inventory: number; operating: number }>();
|
||||
for (const v of visible) {
|
||||
|
||||
Reference in New Issue
Block a user