import { Provide } from "@midwayjs/core"; import { InjectRepository } from "@midwayjs/sequelize"; import { Repository } from "sequelize-typescript"; import { Op } from "sequelize"; import { Context } from "@midwayjs/koa"; import ElectricGateway from "../entity/electric_gateway.entity"; import Customer from "../entity/customer.entity"; import CustomerEquipment from "../entity/customer_equipment.entity"; import SysUserRole from "../entity/sysUserRole.entity"; import SysRole from "../entity/sysRole.entity"; @Provide() export class ElectricGatewayService { @InjectRepository(ElectricGateway) gatewayModel!: Repository; @InjectRepository(Customer) customerModel!: Repository; @InjectRepository(CustomerEquipment) equipmentModel!: Repository; @InjectRepository(SysUserRole) userRoleModel!: Repository; @InjectRepository(SysRole) roleModel!: Repository; private async isAdmin(userId: number): Promise { const userRoles = await this.userRoleModel.findAll({ where: { userId }, include: [this.roleModel] }); return userRoles.some((ur) => (ur as any).role?.roleCode === "ADMIN"); } async list(query: any, ctx: Context): Promise { const page = Number(query.page) || 1; const pageSize = Number(query.pageSize) || 10; const userId = ctx.state.user.userId; const where: any = {}; if (query.keyword) { where[Op.or] = [ { deviceName: { [Op.like]: `%${query.keyword}%` } }, { deviceCode: { [Op.like]: `%${query.keyword}%` } }, { iccImei: { [Op.like]: `%${query.keyword}%` } } ]; } if (query.customerId !== undefined && query.customerId !== "") where.customerId = Number(query.customerId); if (query.equipId !== undefined && query.equipId !== "") where.equipId = Number(query.equipId); if (query.isOnline !== undefined && query.isOnline !== "" && query.isOnline !== null) where.isOnline = Number(query.isOnline); // 非管理员按客户归属自动限定数据范围 if (!(await this.isAdmin(userId))) { const myCustomers = await this.customerModel.findAll({ where: { salesmanId: userId }, attributes: ["id"] }); const ids = myCustomers.map((c) => c.id); if (ids.length === 0) { return { code: 200, message: "获取网关台账列表成功", data: { list: [], total: 0, page: Number(page), pageSize: Number(pageSize) } }; } if (where.customerId !== undefined) { if (!ids.includes(where.customerId)) { return { code: 200, message: "获取网关台账列表成功", data: { list: [], total: 0, page: Number(page), pageSize: Number(pageSize) } }; } } else { where.customerId = { [Op.in]: ids }; } } const { count, rows } = await this.gatewayModel.findAndCountAll({ where, limit: pageSize, offset: (page - 1) * pageSize, order: [["created_at", "DESC"], ["id", "DESC"]], distinct: true }); const list = await this.decorate(rows); return { code: 200, message: "获取网关台账列表成功", data: { list, total: count, page: Number(page), pageSize: Number(pageSize) } }; } async detail(id: number, ctx: Context): Promise { const record = await this.gatewayModel.findByPk(id); if (!record) return { code: 404, message: "网关设备不存在", data: null }; if (!(await this.isAdmin(ctx.state.user.userId))) { const customer = await this.customerModel.findByPk(record.customerId); if (!customer || customer.salesmanId !== ctx.state.user.userId) { return { code: 403, message: "无权限访问该网关设备", data: null }; } } const decorated = await this.decorate([record]); return { code: 200, message: "获取网关设备台账详情成功", data: decorated[0] }; } /** 补全客户/设备展示信息,避免 N+1。 */ private async decorate(rows: ElectricGateway[]): Promise { if (rows.length === 0) return rows as any; const customerIds = [...new Set(rows.map((r) => r.customerId).filter(Boolean))]; const equipIds = [...new Set(rows.map((r) => r.equipId).filter(Boolean))]; const [customers, equips] = await Promise.all([ customerIds.length ? this.customerModel.findAll({ where: { id: { [Op.in]: customerIds } }, attributes: ["id", "customerNo", "customerName"] }) : Promise.resolve([]), equipIds.length ? this.equipmentModel.findAll({ where: { id: { [Op.in]: equipIds } }, attributes: ["id", "equipCode", "equipName"] }) : Promise.resolve([]) ]); const customerMap = new Map(customers.map((c) => [c.id, c])); const equipMap = new Map(equips.map((e) => [e.id, e])); return rows.map((row) => { const json: any = row.toJSON(); const customer: any = customerMap.get(row.customerId); const equip: any = row.equipId ? equipMap.get(row.equipId) : undefined; json.customerNo = customer?.customerNo || ""; json.customerName = customer?.customerName || ""; json.equipCode = equip?.equipCode || ""; json.equipName = equip?.equipName || ""; return json; }); } }