From a97d3b4a19c0fc7586bd02f5b51f609904d5cf15 Mon Sep 17 00:00:00 2001
From: wangrong <wangrong@shsening.com>
Date: 星期六, 25 七月 2026 12:12:00 +0800
Subject: [PATCH] 萤石云设备对接

---
 src/modules/basicdata/controller/admin/iot.ts    |   11 ++
 src/modules/monitor/dto/ys7.dto.ts               |    9 ++
 src/modules/basicdata/service/iot.ts             |  105 ++++++++++++++++++++++++++
 src/modules/monitor/controller/ys7.controller.ts |   20 +++++
 src/configuration.ts                             |   12 +-
 src/modules/push/controller/app/open.ts          |    2 
 src/modules/monitor/config.ts                    |   15 +++
 src/modules/monitor/service/ys7.service.ts       |   56 ++++++++++++++
 8 files changed, 219 insertions(+), 11 deletions(-)

diff --git a/src/configuration.ts b/src/configuration.ts
index 116ab6a..0ba1d73 100644
--- a/src/configuration.ts
+++ b/src/configuration.ts
@@ -8,7 +8,7 @@
   MidwayWebRouterService,
 } from '@midwayjs/core';
 import * as koa from '@midwayjs/koa';
-// import * as crossDomain from '@midwayjs/cross-domain';
+import * as crossDomain from '@midwayjs/cross-domain';
 import * as validate from '@midwayjs/validate';
 import * as info from '@midwayjs/info';
 import * as staticFile from '@midwayjs/static-file';
@@ -18,15 +18,15 @@
 import * as ProdConfig from './config/config.prod';
 import * as cool from '@cool-midway/core';
 import * as upload from '@midwayjs/upload';
-// import * as task from '@cool-midway/task';
-// import * as rpc from '@cool-midway/rpc';
+//import * as task from '@cool-midway/task';
+//import * as rpc from '@cool-midway/rpc';
 
 @Configuration({
   imports: [
     // https://koajs.com/
     koa,
     // 鏄惁寮�鍚法鍩�(娉細椤哄簭涓嶈兘涔辨斁锛侊紒锛�) http://www.midwayjs.org/docs/extensions/cross_domain
-    // crossDomain,
+    crossDomain,
     // 闈欐�佹枃浠舵墭绠� https://midwayjs.org/docs/extensions/static_file
     staticFile,
     // orm https://midwayjs.org/docs/extensions/orm
@@ -40,9 +40,9 @@
     // cool-admin 瀹樻柟缁勪欢 https://cool-js.com
     cool,
     // rpc 寰湇鍔� 杩滅▼璋冪敤
-    // rpc,
+    //rpc,
     // 浠诲姟涓庨槦鍒�
-    // task,
+    //task,
     {
       component: info,
       enabledEnvironment: ['local', 'prod'],
diff --git a/src/modules/basicdata/controller/admin/iot.ts b/src/modules/basicdata/controller/admin/iot.ts
index 4c1e25e..0f129d3 100644
--- a/src/modules/basicdata/controller/admin/iot.ts
+++ b/src/modules/basicdata/controller/admin/iot.ts
@@ -1,4 +1,4 @@
-import { Inject } from '@midwayjs/core';
+import { Body, Inject, Post, Query } from '@midwayjs/core';
 import { CoolController, BaseController } from '@cool-midway/core';
 import { BasicdataIotEntity } from '../../entity/iot';
 import { BasicdataIotService } from '../../service/iot';
@@ -27,10 +27,8 @@
     where: async ctx => {
       const conditions: any[][] = [];
       conditions.push(...(await WithDeptFilterWhere(ctx, { alias: 'a', field: 'departmentId' })));
-
       // 鍏朵粬鍏宠仈琛紙涓句緥锛�
       // conditions.push(...(await deptFilterWhere(ctx, 'd', 'id')));
-
       return conditions;
     },
   },
@@ -38,4 +36,11 @@
 export class AdminBasicdataIotController extends BaseController {
   @Inject()
   basicdataIotService: BasicdataIotService;
+
+  @Post('/getYsDevices', { summary: '鑾峰彇钀ょ煶浜戠洃鎺ц澶�' })
+  async getYsDevices(@Body('businessId') businessId: string) {
+    const devices = await this.basicdataIotService.getYsDevices(businessId);
+    return this.ok(devices);
+  }
+
 }
\ No newline at end of file
diff --git a/src/modules/basicdata/service/iot.ts b/src/modules/basicdata/service/iot.ts
index c97c924..a39f305 100644
--- a/src/modules/basicdata/service/iot.ts
+++ b/src/modules/basicdata/service/iot.ts
@@ -1,8 +1,12 @@
-import { Provide } from '@midwayjs/core';
+import { Inject, Provide } from '@midwayjs/core';
 import { BaseService } from '@cool-midway/core';
 import { InjectEntityModel } from '@midwayjs/typeorm';
 import { Repository } from 'typeorm';
+import { BaseSysDepartmentEntity } from '../../base/entity/sys/department';
 import { BasicdataIotEntity } from '../entity/iot';
+import { BaseSysPermsService } from '../../base/service/sys/perms';
+import { BaseSysParamService } from '../../base/service/sys/param';
+import * as _ from 'lodash';
 
 /**
  * 鏁版嵁婧愬畾涔変俊鎭湇鍔�
@@ -11,4 +15,103 @@
 export class BasicdataIotService extends BaseService {
   @InjectEntityModel(BasicdataIotEntity)
   basicdataIotEntity: Repository<BasicdataIotEntity>;
+
+  @InjectEntityModel(BaseSysDepartmentEntity)
+  baseSysDepartmentEntity: Repository<BaseSysDepartmentEntity>;
+
+  @Inject()
+  baseSysParamService: BaseSysParamService;
+
+  @Inject()
+  baseSysPermsService: BaseSysPermsService;
+
+  @Inject()
+  ctx;
+
+
+  /**
+   * 鑾峰緱閮ㄩ棬鑿滃崟
+   */
+  async list() {
+    const permsDepartmentArr = await this.baseSysPermsService.departmentIds(
+      this.ctx.admin.userId
+    );
+    // 杩囨护閮ㄩ棬鏉冮檺
+    const sql = `
+        (
+            SELECT 
+                a.id AS a_id,
+                a.tenantId AS a_tenantId,
+                a.name AS a_name,
+                a.parentId AS a_parentId,
+                a.orderNum AS a_orderNum
+            FROM base_sys_department a 
+            WHERE 1=1 
+                ${this.setSql(
+                  this.ctx.admin.username !== 'admin',
+                  `and (a.departmentId in (?) `,
+                  [!_.isEmpty(permsDepartmentArr) ? permsDepartmentArr : [null]]
+                )}             
+        )
+        UNION ALL
+        (
+            SELECT 
+                b.businessId AS a_id,
+                a.tenantId AS a_tenantId,
+                b.businessName AS a_name,
+                b.departmentId AS a_parentId,
+                a.orderNum AS a_orderNum
+            FROM t_basicdata_site b
+            LEFT JOIN base_sys_department a ON b.departmentId = a.id
+        )
+        ORDER BY a_orderNum ASC`;
+    const result = await this.nativeQuery(sql);
+    return result;    
+  }
+
+  /**
+   * 鐩戞帶璁惧鏌ヨ
+   */
+  async getYsDevices(businessId: string) {
+    // 淇鍘熷厛key銆乻ecret鍙栧�奸鍊抌ug + 澧炲姞await
+    const ys7_appKey: string = await this.baseSysParamService.dataByKey('ys7.appKey');
+    // departmentId 鏄暟瀛楋紝灏濊瘯杞崲锛涜浆鎹㈠け璐ヨ祴鍊� null
+    const deptId = /^\d+$/.test(businessId) ? Number(businessId) : null;
+    const qb = this.basicdataIotEntity.createQueryBuilder('a')
+      .select([
+        'a.id',
+        'a.iotCode',
+        'a.iotName',
+        'a.iotTypeCode',
+        'a.businessType',
+        'a.businessId',
+        'a.departmentId',
+        'a.iotKey',
+        'a.iotSecret',
+        'a.iotChanel',
+        'a.installLocation',
+        'a.protocol'
+      ])
+      .where('a.iotTypeCode IN (:...typeIds)', {
+        typeIds: ['钀ょ煶浜戝浐瀹氱洃鎺�', '钀ょ煶浜戣溅杞界洃鎺�'],
+      });
+    if (deptId !== null) {
+      qb.andWhere('(a.businessId = :businessId OR a.departmentId = :deptId)', {
+        businessId,
+        deptId
+      });
+    } else {
+      qb.andWhere('a.businessId = :businessId', { businessId });
+    }
+    const result = await qb.orderBy('a.iotName', 'ASC').getMany();
+    const deviceList = result.map(item => {
+      return {
+        ...item,
+        iotKey: ys7_appKey
+      };
+    });
+    return deviceList;
+  }
+
+
 }
\ No newline at end of file
diff --git a/src/modules/monitor/config.ts b/src/modules/monitor/config.ts
new file mode 100644
index 0000000..05331da
--- /dev/null
+++ b/src/modules/monitor/config.ts
@@ -0,0 +1,15 @@
+import { ModuleConfig } from '@cool-midway/core';
+
+export default () => {
+    return {
+        name: 'monitor',
+        description: '钀ょ煶浜戣棰戠洃鎺фā鍧�',
+        enable: true,
+        middleware: [],
+        // globalGuard: [],
+        // globalFilter: [],
+        // globalPipe: [],
+        // 闈欐�佽祫婧愰厤缃紙钀ょ煶涓嶉渶瑕侊紝棰勭暀锛�
+        // static: {},
+    } as ModuleConfig;
+};
\ No newline at end of file
diff --git a/src/modules/monitor/controller/ys7.controller.ts b/src/modules/monitor/controller/ys7.controller.ts
new file mode 100644
index 0000000..e6f8b49
--- /dev/null
+++ b/src/modules/monitor/controller/ys7.controller.ts
@@ -0,0 +1,20 @@
+import { Controller, Post } from '@midwayjs/core';
+import { Inject } from '@midwayjs/core';
+import { BaseController } from '@cool-midway/core';
+import { Ys7Service } from '../service/ys7.service';
+
+@Controller('/admin/monitor/ys7')
+export class Ys7Controller extends BaseController {
+  @Inject()
+  ys7Service: Ys7Service;
+
+  /**
+   * 鑾峰彇钀ょ煶浜� AccessToken
+   * GET/POST 鍧囧彲锛屽墠绔� POST 璋�
+   */
+  @Post('/getToken')
+  async getToken() {
+    const token = await this.ys7Service.getAccessToken();
+    return this.ok(token);
+  }
+}
\ No newline at end of file
diff --git a/src/modules/monitor/dto/ys7.dto.ts b/src/modules/monitor/dto/ys7.dto.ts
new file mode 100644
index 0000000..4006471
--- /dev/null
+++ b/src/modules/monitor/dto/ys7.dto.ts
@@ -0,0 +1,9 @@
+import { Rule, RuleType } from '@midwayjs/validate';
+
+export class GetYs7TokenDTO {
+    @Rule(RuleType.string().required())
+    appKey: string;
+
+    @Rule(RuleType.string().required())
+    appSecret: string;
+}
\ No newline at end of file
diff --git a/src/modules/monitor/service/ys7.service.ts b/src/modules/monitor/service/ys7.service.ts
new file mode 100644
index 0000000..a5294e3
--- /dev/null
+++ b/src/modules/monitor/service/ys7.service.ts
@@ -0,0 +1,56 @@
+import { Provide, Inject } from '@midwayjs/core';
+import { BaseService } from '@cool-midway/core';
+import axios from 'axios';
+import { BaseSysParamService } from '../../base/service/sys/param';
+
+@Provide()
+export class Ys7Service extends BaseService {
+    @Inject()
+    baseSysParamService: BaseSysParamService;
+
+    /**
+     * 鑾峰彇钀ょ煶浜� AccessToken
+     * 鍐呴儴鑷姩璇荤郴缁熷弬鏁帮紝涓嶈蛋缂撳瓨寤鸿涓婂眰鍖呬竴灞� Redis
+     */
+    async getAccessToken(): Promise<{
+        accessToken: string;
+        expireTime: number;
+    }> {
+        // 浠� Cool-Admin 绯荤粺鍙傛暟琛ㄨ鍙�
+        const appKey = await this.baseSysParamService.dataByKey('ys7.appKey');
+        const appSecret = await this.baseSysParamService.dataByKey('ys7.appSecret');
+
+        if (!appKey || !appSecret) {
+            throw new Error('钀ょ煶浜� appKey/appSecret 鏈厤缃紝璇峰湪绯荤粺鍙傛暟涓淮鎶� ys7.appKey / ys7.appSecret');
+        }
+
+        try {
+            const res = await axios.post(
+                'https://open.ys7.com/api/lapp/token/get',
+                new URLSearchParams({
+                    appKey,
+                    appSecret,
+                }),
+                {
+                    headers: {
+                        'Content-Type': 'application/x-www-form-urlencoded',
+                    },
+                    timeout: 8000,
+                }
+            );
+
+            const { code, msg, data } = res.data;
+
+            if (String(code) !== '200') {
+                throw new Error(`钀ょ煶浜戣幏鍙� Token 澶辫触锛�${msg}锛坈ode: ${code}锛塦);
+            }
+
+            return {
+                accessToken: data.accessToken,
+                expireTime: data.expireTime,
+            };
+        } catch (err) {
+            throw err;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/modules/push/controller/app/open.ts b/src/modules/push/controller/app/open.ts
index 1807959..9a89a67 100644
--- a/src/modules/push/controller/app/open.ts
+++ b/src/modules/push/controller/app/open.ts
@@ -28,7 +28,7 @@
   ) {
 
     const CLIENT_ID = String(await this.baseSysParamService.dataByKey('YAOHUA.WEIGHT.CLIENTID')); //'10001';
-    const SECRET = String(await this.baseSysParamService.dataByKey('YAOHUA.WEIGHT.SECRET')); '9001ac9676b8';
+    const SECRET = String(await this.baseSysParamService.dataByKey('YAOHUA.WEIGHT.SECRET')); //'9001ac9676b8';
 
 
     const clientId = headers['clientid'];

--
Gitblit v1.9.1