提交 0d0b07d5 编写于 作者: W wq1234wq

证书管理,设备在线,产品接口

上级 75e58319
<page-header [title]="'设备列表'">
<nz-card [nzBordered]="false" class>
<form nz-form class="search__form" action="search">
<div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }">
<div nz-col nzMd="8" nzSm="24">
<nz-form-item>
<nz-form-label nzFor="name">设备名称</nz-form-label>
<nz-form-control>
<input nz-input [(ngModel)]="q.name" placeholder="请输入设备名称或者Id" [ngModelOptions]="{ standalone: true }" />
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="24" >
<div style="text-align: right">
<nz-card [nzBordered]="false" class>
<form nz-form class="search__form" action="search">
<div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }">
<div nz-col nzMd="8" nzSm="24">
<nz-form-item>
<nz-form-label nzFor="name">设备名称</nz-form-label>
<nz-form-control>
<input nz-input [(ngModel)]="q.name" placeholder="请输入设备名称或者Id" [ngModelOptions]="{ standalone: true }" />
</nz-form-control>
</nz-form-item>
</div>
<div nz-col nzMd="8" nzSm="24">
<nz-form-item>
<nz-form-label nzFor="name">仅显示在线</nz-form-label>
<nz-form-control>
<nz-switch [(ngModel)]="q.onlyActive" [ngModelOptions]="{ standalone: true }" placeholder="仅显示在线设备"></nz-switch>
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="24">
<div style="text-align: right">
<button nz-button type="submit" [nzType]="'primary'" (click)="getData()">搜索</button>
<!--<button nz-button type="submit" (click)="getData()" [nzType]="'primary'" [nzLoading]="loading">查询</button>-->
<button nz-button type="reset" (click)="reset()" class="mx-sm">重置</button>
</div> </div>
</div>
</div>
<!--<button nz-button [nzType]="'primary'" [routerLink]="['/manage/authority/roleform']" [queryParams]="{Id:-1}">
</div>
<!--<button nz-button [nzType]="'primary'" [routerLink]="['/manage/authority/roleform']" [queryParams]="{Id:-1}">
<i nz-icon nzType="plus"></i>
<span>{{ 'button.new' | translate }}</span>
</button>-->
</form>
<div nz-col >
<button nz-button [nzType]="'primary'" (click)="edit('00000000-0000-0000-0000-000000000000')" acl [acl-ability]="137">
<i nz-icon nzType="plus"></i>
<span>{{ 'button.new' | i18n }}</span>
</button>
<button nz-button [nzType]="'primary'" (click)="downlink([])" acl [acl-ability]="137">
<i nz-icon nzType="plus"></i>
<span>设置规则</span>
</button>
<div style="float: right; margin-top: 1rem;">
显示的列:
<nz-checkbox-group
[(ngModel)]="customColumns"
name="customColumns"
(ngModelChange)="st.resetColumns({ emitReload: true })"
></nz-checkbox-group>
</div>
</form>
<div nz-col>
<button nz-button [nzType]="'primary'" (click)="edit('00000000-0000-0000-0000-000000000000')" acl
[acl-ability]="137">
<i nz-icon nzType="plus"></i>
<span>{{ 'button.new' | i18n }}</span>
</button>
<button nz-button [nzType]="'primary'" (click)="downlink([])" acl [acl-ability]="137">
<i nz-icon nzType="plus"></i>
<span>设置规则</span>
</button>
<div style="float: right; margin-top: 1rem;">
显示的列:
<nz-checkbox-group [(ngModel)]="customColumns" name="customColumns"
(ngModelChange)="st.resetColumns({ emitReload: true })"></nz-checkbox-group>
</div>
</nz-card>
<st multiSort
[expandAccordion]="true"
#st
[columns]="columns"
[data]="url"
ps="20"
[page]="page"
[req]="req"
[expand]="expand"
[res]="res"
expandAccordion
(change)="onchange($event)"
>
<ng-template #expand let-item let-index="index" let-column="column">
<nz-card nzTitle="设备属性">
<nz-table [nzNoResult]="null">
<thead>
<tr>
<td>属性名称</td>
<td>属性值</td>
<td>数据侧</td>
<td>时间</td> <td>操作</td>
</tr></thead
>
<tbody>
<tr *ngFor="let _item of cead; let i = index; let odd = odd" [ngClass]="_item.class">
<td>{{ _item.keyName }}</td>
<td>{{ _item.value }}</td>
<td>{{ _item.dataSide }}</td>
<td>{{ _item.dateTime | date: 'yyyy-MM-dd HH:mm:ss' }}</td>
<td>
<button
nz-button
nzType="text"
nzDanger
nz-popconfirm
nzPopconfirmTitle="确认删除属性?"
(nzOnConfirm)="removeprop(item,_item)"
nzPopconfirmPlacement="topLeft"
>
删除
</button>
</td>
</tr>
</tbody>
</nz-table>
</nz-card>
<nz-card nzTitle="遥测数据">
<!-- <nz-tabset> -->
<!-- <nz-tab [nzTitle]="titleTemplate">
</div>
</nz-card>
<st multiSort [expandAccordion]="true" #st [columns]="columns" [data]="url" ps="20" [page]="page" [req]="req"
[expand]="expand" [res]="res" expandAccordion (change)="onchange($event)">
<ng-template #expand let-item let-index="index" let-column="column">
<nz-card nzTitle="设备属性">
<nz-table [nzNoResult]="null">
<thead>
<tr>
<td>属性名称</td>
<td>属性值</td>
<td>数据侧</td>
<td>时间</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let _item of cead; let i = index; let odd = odd" [ngClass]="_item.class">
<td>{{ _item.keyName }}</td>
<td>{{ _item.value }}</td>
<td>{{ _item.dataSide }}</td>
<td>{{ _item.dateTime | date: 'yyyy-MM-dd HH:mm:ss' }}</td>
<td>
<button nz-button nzType="text" nzDanger nz-popconfirm nzPopconfirmTitle="确认删除属性?"
(nzOnConfirm)="removeprop(item,_item)" nzPopconfirmPlacement="topLeft">
删除
</button>
</td>
</tr>
</tbody>
</nz-table>
</nz-card>
<nz-card nzTitle="遥测数据">
<!-- <nz-tabset> -->
<!-- <nz-tab [nzTitle]="titleTemplate">
<ng-template #titleTemplate>
<i nz-icon nzType="area-chart" nzTheme="outline"></i>
图表
......@@ -118,64 +110,57 @@
</div>
</div>
</nz-tab> -->
<!-- <nz-tab [nzTitle]="titleTemplate">
<!-- <nz-tab [nzTitle]="titleTemplate">
<ng-template #titleTemplate>
<i nz-icon ></i>
数据
</ng-template> -->
<nz-table [nzNoResult]="null">
<thead>
<tr>
<td>遥测名称</td>
<td>遥测值</td>
<td>时间</td>
</tr></thead
>
<tbody>
<tr *ngFor="let _item of cetd; let i = index; let odd = odd" [ngClass]="_item.class">
<td>{{ _item.keyName }}</td>
<td>{{ _item.value }}</td>
<td>{{ _item.dateTime | date: 'yyyy-MM-dd HH:mm:ss' }}</td>
</tr>
</tbody>
</nz-table>
<!-- </nz-tab>
<nz-table [nzNoResult]="null">
<thead>
<tr>
<td>遥测名称</td>
<td>遥测值</td>
<td>时间</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let _item of cetd; let i = index; let odd = odd" [ngClass]="_item.class">
<td>{{ _item.keyName }}</td>
<td>{{ _item.value }}</td>
<td>{{ _item.dateTime | date: 'yyyy-MM-dd HH:mm:ss' }}</td>
</tr>
</tbody>
</nz-table>
<!-- </nz-tab>
</nz-tabset> -->
</nz-card>
<nz-card nzTitle="规则">
<nz-table [nzNoResult]="null">
<thead>
<tr>
<td>规则名称</td>
<td>备注</td>
<td>操作</td>
</tr></thead
>
<tbody>
<tr *ngFor="let _item of cerd; let i = index; let odd = odd" >
<td>{{ _item.name }}</td>
<td>{{ _item.ruleDesc }}</td>
<td>
<button
nz-button
nzType="text"
nzDanger
nz-popconfirm
nzPopconfirmTitle="确认删除规则?"
(nzOnConfirm)="removerule(item, _item)"
nzPopconfirmPlacement="topLeft"
>
删除
</button>
</td>
</tr></tbody
>
</nz-table>
</nz-card>
<!-- <nz-card nzTitle="操作">
</nz-card>
<nz-card nzTitle="规则">
<nz-table [nzNoResult]="null">
<thead>
<tr>
<td>规则名称</td>
<td>备注</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let _item of cerd; let i = index; let odd = odd">
<td>{{ _item.name }}</td>
<td>{{ _item.ruleDesc }}</td>
<td>
<button nz-button nzType="text" nzDanger nz-popconfirm nzPopconfirmTitle="确认删除规则?"
(nzOnConfirm)="removerule(item, _item)" nzPopconfirmPlacement="topLeft">
删除
</button>
</td>
</tr>
</tbody>
</nz-table>
</nz-card>
<!-- <nz-card nzTitle="操作">
<div nz-row >
......@@ -195,7 +180,6 @@
</nz-card> -->
</ng-template>
</st>
</page-header>
\ No newline at end of file
</ng-template>
</st>
</page-header>
\ No newline at end of file
......@@ -73,6 +73,7 @@ export class DevicelistComponent implements OnInit, OnDestroy {
pi: number;
ps: number;
sorter: string;
onlyActive:boolean;
customerId: string;
name: string;
// anothor query field:The type you expect
......@@ -80,6 +81,7 @@ export class DevicelistComponent implements OnInit, OnDestroy {
pi: 0,
ps: 20,
sorter: '',
onlyActive:false,
customerId: '',
name: ''
};
......
<page-header [title]="'根证书管理'">
<form nz-form (ngSubmit)="createcert($event)" [formGroup]="form" se-container="1" labelWidth="120">
<se label="域名">
<input nz-input nz-input formControlName="domain" placeholder="域名" />
</se>
<se label="Ca指纹">
<input nz-input nz-input formControlName="caThumbprint" placeholder="域名" />
</se>
<se label="Broker指纹">
<input nz-input nz-input formControlName="brokerThumbprint" placeholder="域名" />
</se>
<button nz-button nzType="primary" type="submit" *ngIf="!installed">生成根证书</button>
</form>
<div nz-row>
<div nz-col class="gutter-row" [nzSpan]="24">
<form nz-form (ngSubmit)="createcert($event)" [formGroup]="form" se-container="1" labelWidth="120">
<se label="域名">
<input nz-input nz-input formControlName="domain" placeholder="域名" />
</se>
<se label="Ca指纹">
<input nz-input nz-input formControlName="caThumbprint" placeholder="域名" />
</se>
<se label="Broker指纹">
<input nz-input nz-input formControlName="brokerThumbprint" placeholder="域名" />
</se>
<button nz-button nzType="primary" type="submit" *ngIf="!installed&&caCertificate">生成根证书</button>
</form>
</div>
</div>
<nz-divider nzOrientation="left" *ngIf="!caCertificate"></nz-divider>
<div nz-row *ngIf="!caCertificate">
<div nz-col class="gutter-row" [nzSpan]="24">
<nz-alert nzType="success" nzDescription="证书尚未配置." nzShowIcon></nz-alert>
</div>
</div>
</page-header>
\ No newline at end of file
......@@ -12,6 +12,7 @@ import { appmessage } from 'src/app/models/appmessage';
export class CertmgrComponent implements OnInit {
form!: FormGroup;
installed = true;
caCertificate=false;
constructor(private http: _HttpClient, private msg: NzMessageService, private fb: FormBuilder,) { }
ngOnInit(): void {
......@@ -31,9 +32,11 @@ export class CertmgrComponent implements OnInit {
next: next => {
if (next.data.installed) {
this.installed = true;
this.caCertificate=next.data.caCertificate;
this.form.patchValue(next.data);
} else {
this.installed = false;
this.caCertificate=next.data.caCertificate;
this.form.patchValue(next.data);
}
},
......
......@@ -131,7 +131,7 @@ namespace IoTSharp.Controllers
var query=from c in _context.Device.Include(c => c.DeviceIdentity) where c.Customer.Id == m.customerId && !c.Deleted && c.Tenant.Id == profile.Tenant select c;
if (m.OnlyActive)
{
var al = from a in _context.AttributeLatest where a.KeyName == Constants._Active select a.DeviceId;
var al = from a in _context.AttributeLatest where a.KeyName == Constants._Active &&a.Value_Boolean==true select a.DeviceId;
query = from x in query where al.Contains( x.Id) select x;
}
if (!string.IsNullOrEmpty(m.Name))
......
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Cryptography;
using System.Threading.Tasks;
using IoTSharp.Contracts;
using IoTSharp.Controllers.Models;
......@@ -30,7 +31,11 @@ namespace IoTSharp.Controllers
_context = context;
_logger = logger;
}
/// <summary>
/// 产品列表
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult<PagedData<ProduceDto>>> List([FromQuery] ProduceParam m)
{
......@@ -49,19 +54,153 @@ namespace IoTSharp.Controllers
total = await _context.Produces.CountAsync(condition),
rows = _context.Produces.Where(condition).Where(condition).Skip((m.offset) * m.limit).Take(m.limit)
.ToList().Select(c => new ProduceDto
{ Id = c.Id, DefaultIdentityType = c.DefaultIdentityType, DefaultTimeout=c.DefaultTimeout, Description= c.Description, Name=c.Name}).ToList()
{ Id = c.Id, DefaultIdentityType = c.DefaultIdentityType, DefaultTimeout = c.DefaultTimeout, Description = c.Description, Name = c.Name }).ToList()
});
}
/// <summary>
///
/// </summary>
/// <param name="produceid"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult<List<ProduceData>>> ProduceDatas(Guid produceid)
{
var result = await _context.ProduceDatas.Include(c => c.Owner).Where(p=>p.Owner.Id==produceid).AsSplitQuery().ToListAsync();
var result = await _context.ProduceDatas.Include(c => c.Owner).Where(p => p.Owner.Id == produceid).AsSplitQuery().ToListAsync();
return new ApiResult<List<ProduceData>>(ApiCode.Success, "OK", result);
}
/// <summary>
/// 获取产品
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult<ProduceAddDto>> Get(Guid id)
{
var result = await _context.Produces.SingleOrDefaultAsync(c => c.Id == id);
if (result != null)
{
return new ApiResult<ProduceAddDto>(ApiCode.Success, "OK", new ProduceAddDto
{
Id = result.Id,
Customer = result.Customer.Id,
Tenant = result.Tenant.Id,
Icon = result.Icon,
DefaultDeviceType = result.DefaultDeviceType,
DefaultIdentityType = result.DefaultIdentityType,
DefaultTimeout = result.DefaultTimeout,
Description = result.Description,
GatewayConfiguration = result.GatewayConfiguration,
GatewayType = result.GatewayType,
Name = result.Name
});
}
else
{
return new ApiResult<ProduceAddDto>(ApiCode.CantFindObject, "Produce is not found", null);
}
}
/// <summary>
/// 删除产品
/// </summary>
/// <param name="produceid"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult<bool>> Delete(Guid produceid)
{
try
{
var produce = await _context.Produces.SingleOrDefaultAsync(c => c.Id == produceid);
if (produce != null)
{
_context.ProduceDatas.RemoveRange(_context.ProduceDatas.Where(c => c.Owner == produce));
await _context.SaveChangesAsync();
_context.Produces.Remove(produce);
await _context.SaveChangesAsync();
return new ApiResult<bool>(ApiCode.Success, "OK", true);
}
return new ApiResult<bool>(ApiCode.CantFindObject, "Produce is not found", false);
}
catch (Exception e)
{
return new ApiResult<bool>(ApiCode.Exception, e.Message, false);
}
}
/// <summary>
/// 新增产品
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult<bool>> Save(ProduceAddDto dto)
{
try
{
var profile = this.GetUserProfile();
var produce = new Produce();
produce.Customer = _context.Customer.Find(profile.Customer);
produce.Tenant = _context.Tenant.Find(profile.Tenant);
produce.DefaultDeviceType = dto.DefaultDeviceType;
produce.DefaultIdentityType=dto.DefaultIdentityType;
produce.DefaultTimeout=dto.DefaultTimeout;
produce.Description=dto.Description;
produce.Name=
dto.Name;
produce.GatewayConfiguration=dto.GatewayConfiguration;
produce.Icon=dto.Icon;
produce.GatewayType=dto.GatewayType;
_context.Produces.Add(produce);
await _context.SaveChangesAsync();
return new ApiResult<bool>(ApiCode.Success, "OK", true);
}
catch (Exception e)
{
return new ApiResult<bool>(ApiCode.Exception, e.Message, false);
}
}
/// <summary>
/// 修改产品
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult<bool>> Update(ProduceAddDto dto)
{
try
{
var produce = await _context.Produces.SingleOrDefaultAsync(c => c.Id == dto.Id);
if (produce != null)
{
produce.DefaultIdentityType = dto.DefaultIdentityType;
produce.DefaultIdentityType = dto.DefaultIdentityType;
produce.DefaultTimeout = dto.DefaultTimeout;
produce.Description = dto.Description;
produce.GatewayConfiguration = dto.GatewayConfiguration;
produce.Name = dto.Name;
produce.Icon = dto.Icon;
_context.Produces.Update(produce);
await _context.SaveChangesAsync();
}
return new ApiResult<bool>(ApiCode.CantFindObject, "Produce is not found", false);
}
catch (Exception e)
{
return new ApiResult<bool>(ApiCode.Exception, e.Message, false);
}
}
}
}
}
using IoTSharp.Contracts;
using IoTSharp.Data;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System;
namespace IoTSharp.Dtos
{
public class ProduceAddDto
{
public Guid Id { get; set; }
/// <summary>
/// 设备名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// ICON file full path
/// </summary>
public string Icon { get; set; }
/// <summary>
/// 网关类型 根据不通网关来处理相关配置
/// </summary>
public GatewayType GatewayType { get; set; } = GatewayType.Unknow;
/// <summary>
/// 网关配置信息, 如果是Unknow 则不使用, 如果是自定义 ,则这里是json字符串。
/// 如果是其他对应的网关, 则这里是 对应的配置文件名。
/// </summary>
public string GatewayConfiguration { get; set; } = string.Empty;
/// <summary>
/// 超时时间 秒数
/// </summary>
public int DefaultTimeout { get; set; } = 300;
/// <summary>
/// 租户
/// </summary>
public Guid Tenant { get; set; }
/// <summary>
/// 客户
/// </summary>
public Guid Customer { get; set; }
/// <summary>
/// 默认认证类型
/// </summary>
[EnumDataType(typeof(IdentityType))]
public IdentityType DefaultIdentityType { get; set; } = IdentityType.AccessToken;
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 默认设备类型
/// </summary>
public DeviceType DefaultDeviceType { get; set; }
}
}
......@@ -514,6 +514,48 @@
</summary>
<returns></returns>
</member>
<member name="M:IoTSharp.Controllers.ProducesController.List(IoTSharp.Controllers.Models.ProduceParam)">
<summary>
产品列表
</summary>
<param name="m"></param>
<returns></returns>
</member>
<member name="M:IoTSharp.Controllers.ProducesController.ProduceDatas(System.Guid)">
<summary>
</summary>
<param name="produceid"></param>
<returns></returns>
</member>
<member name="M:IoTSharp.Controllers.ProducesController.Get(System.Guid)">
<summary>
获取产品
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:IoTSharp.Controllers.ProducesController.Delete(System.Guid)">
<summary>
删除产品
</summary>
<param name="produceid"></param>
<returns></returns>
</member>
<member name="M:IoTSharp.Controllers.ProducesController.Save(IoTSharp.Dtos.ProduceAddDto)">
<summary>
新增产品
</summary>
<param name="dto"></param>
<returns></returns>
</member>
<member name="M:IoTSharp.Controllers.ProducesController.Update(IoTSharp.Dtos.ProduceAddDto)">
<summary>
修改产品
</summary>
<param name="dto"></param>
<returns></returns>
</member>
<member name="M:IoTSharp.Controllers.RulesController.UpdateFlowExpression(IoTSharp.Dtos.UpdateFlowExpression)">
<summary>
更新节点的条件表达式
......@@ -745,6 +787,57 @@
http://localhost/
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.Name">
<summary>
设备名称
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.Icon">
<summary>
ICON file full path
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.GatewayType">
<summary>
网关类型 根据不通网关来处理相关配置
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.GatewayConfiguration">
<summary>
网关配置信息, 如果是Unknow 则不使用, 如果是自定义 ,则这里是json字符串。
如果是其他对应的网关, 则这里是 对应的配置文件名。
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.DefaultTimeout">
<summary>
超时时间 秒数
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.Tenant">
<summary>
租户
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.Customer">
<summary>
客户
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.DefaultIdentityType">
<summary>
默认认证类型
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.Description">
<summary>
描述
</summary>
</member>
<member name="P:IoTSharp.Dtos.ProduceAddDto.DefaultDeviceType">
<summary>
默认设备类型
</summary>
</member>
<member name="T:IoTSharp.Dtos.TelemetryDataQueryDto">
<summary>
查询历史遥测数据请求结构体
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册