c4d7079ac30b4ed0393c2dc831627825c7a545d6..ef05b260b2810232fd770b2ff43b517b91a6b8dd
7 天以前 wangrong
修复部分bug和修改校区监控摄像头合集显示
ef05b2 对比 | 目录
7 天以前 wangrong
修复部分bug和修改校区监控摄像头合集显示
a9a1c7 对比 | 目录
8个文件已删除
5个文件已修改
156 ■■■■ 已修改文件
src/modules/basicdata/controller/admin/site.ts 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/basicdata/service/iot.ts 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/basicdata/service/site.ts 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/monitor/service/capturetask.ts 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/push/controller/app/open.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
uploads/capture/20260810/GT7568358_1786354561815.jpg 补丁 | 查看 | 原始文档 | blame | 历史
uploads/capture/20260810/GT7568358_1786354599954.jpg 补丁 | 查看 | 原始文档 | blame | 历史
uploads/capture/20260810/GU7398831_1786354575450.jpg 补丁 | 查看 | 原始文档 | blame | 历史
uploads/capture/20260810/GV6662505_1786354596817.jpg 补丁 | 查看 | 原始文档 | blame | 历史
uploads/capture/20260810/GV6662514_1786354589019.jpg 补丁 | 查看 | 原始文档 | blame | 历史
uploads/capture/20260810/GV7474259_1786354585367.jpg 补丁 | 查看 | 原始文档 | blame | 历史
uploads/capture/20260810/GV7474275_1786354579899.jpg 补丁 | 查看 | 原始文档 | blame | 历史
uploads/capture/20260810/GV7474291_1786354592342.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/modules/basicdata/controller/admin/site.ts
@@ -2,18 +2,13 @@
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: [
      {
@@ -23,15 +18,6 @@
        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 {}
src/modules/basicdata/service/iot.ts
@@ -114,4 +114,24 @@
    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;
  }
}
src/modules/basicdata/service/site.ts
@@ -1,14 +1,112 @@
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;
  }
}
src/modules/monitor/service/capturetask.ts
@@ -108,7 +108,7 @@
                // 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);
@@ -121,9 +121,9 @@
                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 = {
@@ -278,7 +278,7 @@
        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) {
src/modules/push/controller/app/open.ts
@@ -116,7 +116,7 @@
      this.ctx.body = { messageId: '' };
      return;
    }
    console.log('【萤石云原始报文】:', rawBody.slice(0, 500));
    console.log('【萤石云原始报文】:', rawBody);
    let msg: any;
    try {
      msg = JSON.parse(rawBody);
uploads/capture/20260810/GT7568358_1786354561815.jpg
Binary files differ
uploads/capture/20260810/GT7568358_1786354599954.jpg
Binary files differ
uploads/capture/20260810/GU7398831_1786354575450.jpg
Binary files differ
uploads/capture/20260810/GV6662505_1786354596817.jpg
Binary files differ
uploads/capture/20260810/GV6662514_1786354589019.jpg
Binary files differ
uploads/capture/20260810/GV7474259_1786354585367.jpg
Binary files differ
uploads/capture/20260810/GV7474275_1786354579899.jpg
Binary files differ
uploads/capture/20260810/GV7474291_1786354592342.jpg
Binary files differ