import { Init, Provide } from '@midwayjs/core'; import { BaseService, CoolCommException } from '@cool-midway/core'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Repository } from 'typeorm'; import { NfcDeviceEntity } from '../entity/device'; /** * 管理后台 serviceApis:绑定 / 换绑 */ export interface NfcBindParams { uid: string; cardId: number; } /** * 管理后台 serviceApis:仅需芯片 UID */ export interface NfcUidParams { uid: string; } /** * NFC 绑定激活服务 * 硬件只写 UID/短链,后台随时换绑名片,无需重烧 */ @Provide() export class NfcBindService extends BaseService { @InjectEntityModel(NfcDeviceEntity) nfcDeviceEntity: Repository; @Init() async init() { await super.init(); this.setEntity(this.nfcDeviceEntity); } /** * 绑定名片并激活 * 兼容管理后台 serviceApis:POST body 为单参数对象 { uid, cardId } */ async bind(params: NfcBindParams): Promise { const device = await this.requireDevice(params?.uid); if (device.status === 'suspended') { throw new CoolCommException('已挂失不可绑定'); } const cardId = this.requireCardId(params?.cardId); device.cardId = cardId; device.status = 'active'; return (await this.nfcDeviceEntity.save(device)) as NfcDeviceEntity; } /** * 激活已绑定名片的 unbound 设备 * 兼容管理后台 serviceApis:POST body 为单参数对象 { uid } */ async activate(params: NfcUidParams): Promise { const device = await this.requireDevice(params?.uid); if (device.status === 'suspended') { throw new CoolCommException('已挂失不可激活'); } if (device.cardId == null || !Number(device.cardId)) { throw new CoolCommException('未绑定名片,无法激活'); } device.status = 'active'; return (await this.nfcDeviceEntity.save(device)) as NfcDeviceEntity; } /** * 更换已激活设备绑定的名片,不改 UID * 兼容管理后台 serviceApis:POST body 为单参数对象 { uid, cardId } */ async switchCard(params: NfcBindParams): Promise { const device = await this.requireDevice(params?.uid); if (device.status !== 'active') { throw new CoolCommException( device.status === 'suspended' ? '已挂失不可换绑,请先解冻' : '仅已激活设备可换绑' ); } const cardId = this.requireCardId(params?.cardId); device.cardId = cardId; return (await this.nfcDeviceEntity.save(device)) as NfcDeviceEntity; } /** * 解绑名片,状态回到 unbound * 兼容管理后台 serviceApis:POST body 为单参数对象 { uid } */ async unbind(params: NfcUidParams): Promise { const device = await this.requireDevice(params?.uid); if (device.status === 'suspended') { throw new CoolCommException('已挂失不可解绑,请先解冻'); } device.cardId = null; device.status = 'unbound'; return (await this.nfcDeviceEntity.save(device)) as NfcDeviceEntity; } private async requireDevice(uid?: string): Promise { const chipUid = String(uid || '').trim(); if (!chipUid) { throw new CoolCommException('设备 UID 不能为空'); } const device = await this.nfcDeviceEntity.findOneBy({ uid: chipUid }); if (!device) { throw new CoolCommException('设备未在台账中'); } return device; } private requireCardId(cardId?: number): number { const id = Number(cardId); if (!id) { throw new CoolCommException('名片 ID 不能为空'); } return id; } }