- 重建 electric_line 表结构(迁移20261024_icc_line_rebuild.sql并同步db_init/db_seed):删building_id/floor_no/location/icc_device_code占位字段,equip_id改可空,新增imei/gateway_id/type_code/type_name/fire_system_code/fire_system_name/part_unit_loop_code/channel_no/channel_sn/produce_date,gateway_id外键→electric_gateway - 同步服务IccLineSyncService复用OAuth2真实鉴权分页拉取探测器(POST /detector/subsystem/page,pageSize=50短页停止),按line_code(detectorCode)幂等upsert写icc_sync_log;customer_id由orgCode→customer.icc_code解析、gateway_id由parentCode→electric_gateway.device_code匹配、equip_id同步不填充 - 列表接口返回gateway/type/imei等新字段,keyword检索含imei;前端台账页更新为新列(IMEI/所属网关/探测器类型/回路通道/消防系统/生产日期),保留手动同步按钮与筛选 - 更新系统设计文档electric_line表定义与spec(add-icc-line-sync)
145 lines
5.5 KiB
TypeScript
145 lines
5.5 KiB
TypeScript
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 ElectricLine from "../entity/electric_line.entity";
|
|
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 ElectricLineService {
|
|
@InjectRepository(ElectricLine)
|
|
lineModel!: Repository<ElectricLine>;
|
|
|
|
@InjectRepository(Customer)
|
|
customerModel!: Repository<Customer>;
|
|
|
|
@InjectRepository(CustomerEquipment)
|
|
equipmentModel!: Repository<CustomerEquipment>;
|
|
|
|
@InjectRepository(ElectricGateway)
|
|
gatewayModel!: Repository<ElectricGateway>;
|
|
|
|
@InjectRepository(SysUserRole)
|
|
userRoleModel!: Repository<SysUserRole>;
|
|
|
|
@InjectRepository(SysRole)
|
|
roleModel!: Repository<SysRole>;
|
|
|
|
private async isAdmin(userId: number): Promise<boolean> {
|
|
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<any> {
|
|
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] = [
|
|
{ lineName: { [Op.like]: `%${query.keyword}%` } },
|
|
{ lineCode: { [Op.like]: `%${query.keyword}%` } },
|
|
{ imei: { [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.status !== undefined && query.status !== "" && query.status !== null) where.status = Number(query.status);
|
|
|
|
// 非管理员按客户归属自动限定数据范围
|
|
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.lineModel.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<any> {
|
|
const record = await this.lineModel.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: ElectricLine[]): Promise<any[]> {
|
|
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 gatewayIds = [...new Set(rows.map((r) => r.gatewayId).filter(Boolean))];
|
|
|
|
const [customers, equips, gateways] = 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([]),
|
|
gatewayIds.length
|
|
? this.gatewayModel.findAll({
|
|
where: { id: { [Op.in]: gatewayIds } },
|
|
attributes: ["id", "deviceCode", "deviceName"]
|
|
})
|
|
: Promise.resolve([])
|
|
]);
|
|
|
|
const customerMap = new Map(customers.map((c) => [c.id, c]));
|
|
const equipMap = new Map(equips.map((e) => [e.id, e]));
|
|
const gatewayMap = new Map(gateways.map((g) => [g.id, g]));
|
|
|
|
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;
|
|
const gateway: any = row.gatewayId ? gatewayMap.get(row.gatewayId) : undefined;
|
|
json.customerNo = customer?.customerNo || "";
|
|
json.customerName = customer?.customerName || "";
|
|
json.equipCode = equip?.equipCode || "";
|
|
json.equipName = equip?.equipName || "";
|
|
json.gatewayCode = gateway?.deviceCode || "";
|
|
json.gatewayName = gateway?.deviceName || "";
|
|
return json;
|
|
});
|
|
}
|
|
} |