| | |
| | | import { BasicdataSiteEntity } from '../../entity/site'; |
| | | import { BasicdataSiteService } from '../../service/site'; |
| | | import { BaseSysDepartmentEntity } from '../../../base/entity/sys/department'; |
| | | import { WithDeptFilterWhere } from '../../../base/middleware/with-dept-filter-where' |
| | | |
| | | /** |
| | | * 站点信息后台管理 |
| | | */ |
| | | @CoolController({ |
| | | api: ['add', 'delete', 'update', 'info', 'list', 'page'], |
| | | entity: BasicdataSiteEntity, |
| | | service: BasicdataSiteService, |
| | | pageQueryOp: { |
| | | keyWordLikeFields: ['a.name', 'a.address', 'a.leader'], |
| | | fieldEq: ['a.departmentId', 'a.siteType', 'a.status'], |
| | | // ✅ page 方法已在 Service 中重写,这里配置仅作兜底 |
| | | select: ['a.*', 'b.name AS departmentName'], |
| | | join: [ |
| | | { |
| | |
| | | type: 'leftJoin', |
| | | }, |
| | | ], |
| | | where: async ctx => { |
| | | const conditions: any[][] = []; |
| | | conditions.push(...(await WithDeptFilterWhere(ctx, { alias: 'a', field: 'departmentId' }))); |
| | | |
| | | // 其他关联表(举例) |
| | | // conditions.push(...(await deptFilterWhere(ctx, 'd', 'id'))); |
| | | |
| | | return conditions; |
| | | }, |
| | | }, |
| | | }) |
| | | export class AdminBasicdataSiteController extends BaseController { } |
| | | export class AdminBasicdataSiteController extends BaseController {} |
| | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 递归获取部门及其所有子部门 ID |
| | | */ |
| | | async getDepartmentAndChildren(deptId: number): Promise<number[]> { |
| | | const result: number[] = [deptId]; |
| | | const findChildren = async (pid: number) => { |
| | | const children = await this.baseSysDepartmentEntity |
| | | .createQueryBuilder('d') |
| | | .select('d.id') |
| | | .where('d.parentId = :pid', { pid }) |
| | | .getMany(); |
| | | for (const c of children) { |
| | | result.push(c.id); |
| | | await findChildren(c.id); |
| | | } |
| | | }; |
| | | await findChildren(deptId); |
| | | return result; |
| | | } |
| | | |
| | | } |
| | |
| | | import { Provide } from '@midwayjs/core'; |
| | | import { Provide, Inject, Context } from '@midwayjs/core'; |
| | | import { BaseService } from '@cool-midway/core'; |
| | | import { InjectEntityModel } from '@midwayjs/typeorm'; |
| | | import { Repository } from 'typeorm'; |
| | | import { BasicdataSiteEntity } from '../entity/site'; |
| | | import { BaseSysDepartmentEntity } from '../../base/entity/sys/department'; |
| | | import { WithDeptFilterWhere } from '../../base/middleware/with-dept-filter-where'; |
| | | import { Context as KoaContext } from '@midwayjs/koa'; |
| | | |
| | | /** |
| | | * 站点服务 |
| | | */ |
| | | @Provide() |
| | | export class BasicdataSiteService extends BaseService { |
| | | @InjectEntityModel(BasicdataSiteEntity) |
| | | basicdataSiteEntity: Repository<BasicdataSiteEntity>; |
| | | } |
| | | |
| | | @InjectEntityModel(BaseSysDepartmentEntity) |
| | | baseSysDepartmentEntity: Repository<BaseSysDepartmentEntity>; |
| | | |
| | | @Inject() |
| | | ctx: KoaContext; |
| | | |
| | | /** |
| | | * 重写 page —— 显式列出字段,避免 a.* 的别名问题 |
| | | */ |
| | | async page(query: any) { |
| | | const { |
| | | page = 1, |
| | | size = 20, |
| | | departmentId, |
| | | siteType, |
| | | status, |
| | | keyWord, |
| | | sort, |
| | | order, |
| | | } = query; |
| | | const qb = this.basicdataSiteEntity |
| | | .createQueryBuilder('a') |
| | | .leftJoin(BaseSysDepartmentEntity, 'b', 'a.departmentId = b.id') |
| | | .select([ |
| | | 'a.id', |
| | | 'a.businessId', |
| | | 'a.businessName', |
| | | 'a.departmentId', |
| | | 'a.siteType', |
| | | 'a.address', |
| | | 'a.leader', |
| | | 'a.longitude', |
| | | 'a.latitude', |
| | | 'a.photo', |
| | | 'a.status', |
| | | 'a.remark', |
| | | 'a.createTime', |
| | | 'a.updateTime', |
| | | 'b.name AS departmentName', |
| | | ]); |
| | | const authConds = await WithDeptFilterWhere(this.ctx, { |
| | | alias: 'a', |
| | | field: 'departmentId', |
| | | }); |
| | | for (const [sql, params] of authConds) { |
| | | qb.andWhere(sql, params); |
| | | } |
| | | if (departmentId) { |
| | | const deptIds = await this.getDepartmentAndChildren(Number(departmentId)); |
| | | qb.andWhere('a.departmentId IN (:deptIds)', { deptIds }); |
| | | } |
| | | if (siteType !== undefined && siteType !== '') { |
| | | qb.andWhere('a.siteType = :siteType', { siteType }); |
| | | } |
| | | if (status !== undefined && status !== '') { |
| | | qb.andWhere('a.status = :status', { status: Number(status) }); |
| | | } |
| | | if (keyWord) { |
| | | qb.andWhere( |
| | | '(a.businessId LIKE :kw OR a.businessName LIKE :kw OR a.address LIKE :kw OR a.leader LIKE :kw)', |
| | | { kw: `%${keyWord}%` } |
| | | ); |
| | | } |
| | | const sortField = order || 'createTime'; |
| | | const sortDir = sort === 'asc' ? 'ASC' : 'DESC'; |
| | | qb.orderBy(`a.${sortField}`, sortDir); |
| | | const skip = (Number(page) - 1) * Number(size); |
| | | const [list, total] = await qb |
| | | .offset(skip) |
| | | .limit(Number(size)) |
| | | .getManyAndCount(); |
| | | |
| | | return { |
| | | list, |
| | | pagination: { page: Number(page), size: Number(size), total }, |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * 递归获取部门及其所有子部门 ID |
| | | */ |
| | | async getDepartmentAndChildren(deptId: number): Promise<number[]> { |
| | | const result: number[] = [deptId]; |
| | | const findChildren = async (pid: number) => { |
| | | const children = await this.baseSysDepartmentEntity |
| | | .createQueryBuilder('d') |
| | | .select('d.id') |
| | | .where('d.parentId = :pid', { pid }) |
| | | .getMany(); |
| | | for (const c of children) { |
| | | result.push(c.id); |
| | | await findChildren(c.id); |
| | | } |
| | | }; |
| | | await findChildren(deptId); |
| | | return result; |
| | | } |
| | | } |
| | |
| | | |
| | | // 4. 本地目录 |
| | | const dateDir = new Date().toISOString().slice(0, 10).replace(/-/g, ''); |
| | | const localDir = path.join(process.cwd(), 'uploads', 'capture', dateDir); |
| | | const localDir = path.join(process.cwd(), 'upload', 'capture', dateDir); |
| | | fs.mkdirSync(localDir, { recursive: true }); |
| | | console.log('[Capture] 本地目录=', localDir); |
| | | |
| | |
| | | console.log('[Capture] 图片下载完成'); |
| | | |
| | | const relativePath = path |
| | | .relative(path.join(process.cwd(), 'uploads'), dest) |
| | | .relative(path.join(process.cwd(), 'upload'), dest) |
| | | .replace(/\\/g, '/'); |
| | | const localUrl = `/uploads/${relativePath}`; |
| | | const localUrl = `/upload/${relativePath}`; |
| | | console.log('[Capture] localUrl=', localUrl); |
| | | |
| | | const entity = { |
| | |
| | | const spaceId = await this.getSpaceID(); |
| | | const imgs = await this.queryCaptureImages(deviceSerial, spaceId); |
| | | const dateDir = new Date().toISOString().slice(0, 10).replace(/-/g, ''); |
| | | const localDir = path.join(process.cwd(), 'uploads', 'capture', dateDir); |
| | | const localDir = path.join(process.cwd(), 'upload', 'capture', dateDir); |
| | | fs.mkdirSync(localDir, { recursive: true }); |
| | | |
| | | for (const img of imgs) { |
| | |
| | | this.ctx.body = { messageId: '' }; |
| | | return; |
| | | } |
| | | console.log('【萤石云原始报文】:', rawBody.slice(0, 500)); |
| | | console.log('【萤石云原始报文】:', rawBody); |
| | | let msg: any; |
| | | try { |
| | | msg = JSON.parse(rawBody); |