diff --git a/IoTSharp.Contracts/Enums.cs b/IoTSharp.Contracts/Enums.cs
index 1b027e0982dcc904c801c94f6f4c73443882ed63..81d383809a800199ca35e8c2fbb6ae5542982a37 100644
--- a/IoTSharp.Contracts/Enums.cs
+++ b/IoTSharp.Contracts/Enums.cs
@@ -152,6 +152,9 @@ namespace IoTSharp.Contracts
Device = 0,
Gateway = 1
}
+
+ [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
+ [JsonConverter(typeof(StringEnumConverter))]
public enum GatewayType
{
Unknow=0,
diff --git a/IoTSharp/ClientApp/src/app/routes/devices/deviceform/deviceform.component.html b/IoTSharp/ClientApp/src/app/routes/devices/deviceform/deviceform.component.html
index 77088d8e40629c76f6a83f16dd3c2e3e543bc0fb..ea66ea73be3681537ec48ac7401db6521ddfcfd0 100644
--- a/IoTSharp/ClientApp/src/app/routes/devices/deviceform/deviceform.component.html
+++ b/IoTSharp/ClientApp/src/app/routes/devices/deviceform/deviceform.component.html
@@ -11,7 +11,13 @@
-
+
+
+
+
+
+
+
@@ -32,8 +38,6 @@
-
-
diff --git a/IoTSharp/ClientApp/src/app/routes/devices/deviceform/deviceform.component.ts b/IoTSharp/ClientApp/src/app/routes/devices/deviceform/deviceform.component.ts
index e0a6272b79031bc6b1a0cc5f640e782b298f9e69..c3c428677634d5fa2aeff5df89916161bf0e17de 100644
--- a/IoTSharp/ClientApp/src/app/routes/devices/deviceform/deviceform.component.ts
+++ b/IoTSharp/ClientApp/src/app/routes/devices/deviceform/deviceform.component.ts
@@ -32,7 +32,7 @@ export class DeviceformComponent implements OnInit {
) {}
form!: FormGroup;
submitting = false;
-
+ deviceproduce = [];
devicemodel: devicemodel[] = [];
data: deviceitem = {
@@ -47,20 +47,26 @@ export class DeviceformComponent implements OnInit {
name: [null, [Validators.required, Validators.pattern(/^(\s+\S+\s*)*(?!\s).*$/)]],
deviceType: [null, [Validators.required]],
customerId: [null, []],
- // deviceModelId: [null, []],
+ produceId: [null, []],
timeout: [300, []],
id: [Guid.EMPTY, []],
identityType: [Guid.EMPTY, []]
});
- this._httpClient.post('api/deviceModel/index', { offset: 0, limit: 100 }).subscribe({
+ // this._httpClient.post('api/deviceModel/index', { offset: 0, limit: 100 }).subscribe({
+ // next: next => {
+ // this.devicemodel = next.data.rows;
+ // },
+ // error: error => {},
+ // complete: () => {}
+ // });
+ this._httpClient.get('api/produces/list', { offset: 0, limit: -1 }).subscribe({
next: next => {
- this.devicemodel = next.data.rows;
+ this.deviceproduce = next.data.rows;
},
error: error => {},
complete: () => {}
});
-
if (this.params.id !== Guid.EMPTY) {
concat(
this._httpClient.get>('api/Devices/' + this.params.id).pipe(
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/produce.module.ts b/IoTSharp/ClientApp/src/app/routes/produce/produce.module.ts
index b48295a66f2000f72fa425ad3d44ea49cc3f889c..d7b616cb89584b173e9606b6b7a24f7904c73013 100644
--- a/IoTSharp/ClientApp/src/app/routes/produce/produce.module.ts
+++ b/IoTSharp/ClientApp/src/app/routes/produce/produce.module.ts
@@ -1,10 +1,12 @@
import { NgModule } from '@angular/core';
import { SharedModule } from '@shared';
import { ProduceRoutingModule } from './produce-routing.module';
+import { ProducedatadictionaryformComponent } from './producedatadictionaryform/producedatadictionaryform.component';
+import { ProducedataformComponent } from './producedataform/producedataform.component';
const COMPONENTS = [
-
+ ProducedataformComponent,ProducedatadictionaryformComponent
];
@NgModule({
@@ -12,4 +14,4 @@ const COMPONENTS = [
providers: [],
declarations: COMPONENTS
})
-export class SettingsModule {}
+export class ProduceModule {}
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.html b/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..0ef7a68d4bb01dc2c3ca3e1596678c361df709e2
--- /dev/null
+++ b/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.html
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+ {{ item.keyName }}
+
+
+
+
+ {{ item.displayName }}
+
+
+
+
+ {{ item.unit }}
+
+
+
+
+ {{ item.unitExpression }}
+
+
+
+
+
+ {{ item.unitConvert }}
+
+
+
+
+
+
+ {{ item.keyDesc }}
+
+
+
+ {{ item.defaultValue }}
+
+
+
+
+
+
+
+ {{ item.display }}
+
+
+
+
+
+ {{ item.place0 }}
+
+
+
+
+
+
+ {{ item.tag }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.dataType}}
+
+
+
+
\ No newline at end of file
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.less b/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.less
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.spec.ts b/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..651f943bb989270dce6703ee5e7ffe935953b866
--- /dev/null
+++ b/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ProducedatadictionaryformComponent } from './producedatadictionaryform.component';
+
+describe('ProducedatadictionaryformComponent', () => {
+ let component: ProducedatadictionaryformComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ ProducedatadictionaryformComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ProducedatadictionaryformComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.ts b/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d5ab8f306940caeef8951f41968b7fc70a7340bd
--- /dev/null
+++ b/IoTSharp/ClientApp/src/app/routes/produce/producedatadictionaryform/producedatadictionaryform.component.ts
@@ -0,0 +1,127 @@
+import { Component, Input, OnInit, ViewChild } from '@angular/core';
+import { STComponent, STData, STColumn } from '@delon/abc/st';
+import { _HttpClient } from '@delon/theme';
+import { Guid } from 'guid-typescript';
+import { NzMessageService } from 'ng-zorro-antd/message';
+import { appmessage } from 'src/app/models/appmessage';
+
+@Component({
+ selector: 'app-producedatadictionaryform',
+ templateUrl: './producedatadictionaryform.component.html',
+ styleUrls: ['./producedatadictionaryform.component.less']
+})
+export class ProducedatadictionaryformComponent implements OnInit {
+
+
+ @Input() id: string = Guid.EMPTY;
+ @ViewChild('st') private st!: STComponent;
+ dictionaryData: STData[] = []
+
+ columns: STColumn[] = [
+
+ { title: '字段名称', index: 'keyName', render: 'keyNameTpl' },
+ { title: '字段显示名称', index: 'displayName', render: 'displayNameTpl' },
+ { title: '单位', index: 'unit', render: 'unitTpl' },
+ { title: '单位转换表达式', index: 'unitExpression', render: 'unitExpressionTpl' },
+ { title: 'UnitConvert', index: 'unitConvert', render: 'unitConvertTpl' },
+ { title: '字段备注', index: 'keyDesc', render: 'keyDescTpl' },
+ { title: '默认值', index: 'defaultValue', render: 'defaultValueTpl' },
+ { title: '是否显示', index: 'display', render: 'displayTpl' },
+ { title: '位置名称', index: 'place0', render: 'place0Tpl' },
+ { title: 'Tag', index: 'tag', render: 'tagtpl' },
+
+ { title: '数据类型', index: 'dataType', render: 'dataTypeTpl' },
+ {
+ title: '操作',
+ buttons: [
+ {
+ text: `编辑`,
+ iif: i => !i.edit,
+ click: i => this.updateEdit(i, true),
+ },
+ {
+ text: `删除`,
+ iif: i => !i.edit, pop: {
+ title: '确认删除属性?',
+ okType: 'danger',
+ icon: 'warning',
+ },
+ click: i => this.remove(i),
+ },
+ {
+ text: `保存`,
+ iif: i => i.edit,
+ click: (i, v) => {
+ console.log(i)
+ this.submit(i);
+ },
+ },
+ {
+ text: `取消`,
+ iif: i => i.edit,
+ click: i => this.updateEdit(i, false),
+ },
+ ],
+ },
+ ];
+ constructor(private msg: NzMessageService, private http: _HttpClient,) {
+
+
+
+ }
+
+ ngOnInit(): void {
+
+ this.http.get>('api/produces/getProduceDictionary?produceId=' + this.id)
+ .subscribe({
+ next: next => {
+ this.dictionaryData = next.data;
+ },
+
+ error: error => {
+
+ },
+
+ complete: () => { }
+
+ });
+ }
+
+ private submit(i: STData): void {
+ this.updateEdit(i, false)
+ this.dictionaryData = this.st.list;
+
+ }
+
+
+ private remove(i: STData) {
+ this.st.removeRow(i); this.dictionaryData = this.st.list;
+ }
+ private updateEdit(i: STData, edit: boolean): void {
+
+ this.st.setRow(i, { edit }, { refreshSchema: true });
+ }
+ _id = 0;
+ newRow() {
+ this.dictionaryData = [{ edit: true }, ...this.dictionaryData]
+ }
+
+ saveRow() {
+ this.http.post('api/produces/editProduceDictionary', { produceId: this.id, produceDictionaryData: this.dictionaryData }).subscribe(
+ {
+ next: next => {
+
+ if (next.code === 10000) {
+ this.msg.success('保存成功')
+ }else{
+ this.msg.warning('保存失败:'+next.msg)
+ }
+
+ },
+ error: error => { },
+ complete: () => { }
+ }
+ );
+ }
+
+}
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.html b/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..808e1886be81a8623048a237a8807d7c51eac6ad
--- /dev/null
+++ b/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ {{ item.keyName }}
+
+
+
+
+
+
+
+
+
+
+ {{ item.dataSide }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.type}}
+
+
+
+
\ No newline at end of file
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.less b/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.less
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.spec.ts b/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..91c14906c231bbd225a9115c966e8243708e1fc5
--- /dev/null
+++ b/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ProducedataformComponent } from './producedataform.component';
+
+describe('ProducedataformComponent', () => {
+ let component: ProducedataformComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ ProducedataformComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ProducedataformComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.ts b/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b03fb2e953a58f804b2ce5089de279eccff7e39d
--- /dev/null
+++ b/IoTSharp/ClientApp/src/app/routes/produce/producedataform/producedataform.component.ts
@@ -0,0 +1,102 @@
+import { Component, Input, OnInit, ViewChild } from '@angular/core';
+import { STComponent, STData, STColumn } from '@delon/abc/st';
+import { _HttpClient } from '@delon/theme';
+import { Guid } from 'guid-typescript';
+import { NzMessageService } from 'ng-zorro-antd/message';
+import { appmessage } from 'src/app/models/appmessage';
+
+@Component({
+ selector: 'app-producedataform',
+ templateUrl: './producedataform.component.html',
+ styleUrls: ['./producedataform.component.less']
+})
+export class ProducedataformComponent implements OnInit {
+
+ @Input() id: string = Guid.EMPTY;
+ @ViewChild('st') private st!: STComponent;
+ produceData: STData[] = []
+
+ columns: STColumn[] = [
+ { title: 'KeyName', index: 'keyName', render: 'ColumnTitleTpl' },
+ { title: '数据侧', index: 'dataSide', render: 'ColumnTypeTpl' },
+ { title: '数据类型', index: 'type', render: 'ColumnDataTypeTpl' },
+ {
+ title: '操作',
+ buttons: [
+ {
+ text: `编辑`,
+ iif: i => !i.edit,
+ click: i => this.updateEdit(i, true),
+ },
+ {
+ text: `删除`,
+ iif: i => !i.edit, pop: {
+ title: '确认删除属性?',
+ okType: 'danger',
+ icon: 'warning',
+ },
+ click: i => this.remove(i),
+ },
+ {
+ text: `保存`,
+ iif: i => i.edit,
+ click: (i, v) => {
+ console.log(i)
+ this.submit(i);
+ },
+ },
+ {
+ text: `取消`,
+ iif: i => i.edit,
+ click: i => this.updateEdit(i, false),
+ },
+ ],
+ },
+ ];
+ constructor(private msg: NzMessageService, private http: _HttpClient,) {
+
+
+
+ }
+
+ ngOnInit(): void {
+
+ this.http.get>('api/produces/GetProduceData?produceId=' + this.id).subscribe(next => {
+ this.produceData = next.data;
+ }, error => {
+
+ }, () => { });
+ }
+
+ private submit(i: STData): void {
+ this.updateEdit(i, false)
+ this.produceData = this.st.list;
+
+ }
+
+
+ private remove(i: STData) {
+ this.st.removeRow(i); this.produceData = this.st.list;
+ }
+ private updateEdit(i: STData, edit: boolean): void {
+
+ this.st.setRow(i, { edit }, { refreshSchema: true });
+ }
+ _id = 0;
+ newRow() {
+ this.produceData = [{ edit: true }, ...this.produceData]
+ }
+
+ saveRow() {
+ this.http.post('api/produces/editProduceData', { produceId: this.id, produceData: this.produceData }).subscribe(next => {
+ if (next.code === 10000) {
+ this.msg.success('保存成功')
+ }else{
+ this.msg.warning('保存失败:'+next.msg)
+ }}, error => { }, () => { });
+ }
+
+
+
+
+}
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.html b/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.html
index 89f00de83b7119e190152c567ae793a3beca5db6..b902b552dc6ce37803797eac5fc543355adcf604 100644
--- a/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.html
+++ b/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.html
@@ -5,19 +5,45 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
+
+
@@ -28,6 +54,9 @@
+
+
+
\ No newline at end of file
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.less b/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.less
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e399a368d839e3ebde4bb843d14d520401610d03 100644
--- a/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.less
+++ b/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.less
@@ -0,0 +1,19 @@
+.editor {
+ height: 100%;
+ }
+
+ .full-screen {
+ position: fixed;
+ z-index: 999;
+ height: 100%;
+ left: 0;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ }
+ nz-select{
+ width: 100%;
+ }
+ .exgroup{
+ width: 100%;
+ }
\ No newline at end of file
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.ts b/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.ts
index 3125b8784c8b4b539bd5a3a88b462b20f42d2835..96436ac048f9b21286d176d39e8405845d3e83eb 100644
--- a/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.ts
+++ b/IoTSharp/ClientApp/src/app/routes/produce/produceform/produceform.component.ts
@@ -14,10 +14,10 @@ import { devicemodel, deviceitem } from 'src/app/models/deviceitem';
styleUrls: ['./produceform.component.less']
})
export class ProduceformComponent implements OnInit {
+ fullScreen = false;
- isManufactorLoading: Boolean = false;
- optionList: any;
- @Input() id=Guid.EMPTY;
+
+ @Input() id = Guid.EMPTY;
nodes = [];
title: string = '';
loading = false;
@@ -27,67 +27,98 @@ export class ProduceformComponent implements OnInit {
private fb: FormBuilder,
private msg: NzMessageService,
private drawerRef: NzDrawerRef
- ) {}
+ ) { }
form!: FormGroup;
submitting = false;
- devicemodel: devicemodel[] = [];
- data: deviceitem = {
- name: '',
- deviceType: '',
- customerId: '',
- id: Guid.EMPTY,
- identityType: ''
- };
+
ngOnInit() {
this.form = this.fb.group({
- name: [null, [Validators.required ]],
- description: ['', []],
- defaultTimeout: [300, []],
id: [Guid.EMPTY, []],
- defaultIdentityType: ['', []]
+ name: [null, [Validators.required]],
+ icon: ['', []],
+ gatewayType: ['Unknow', []],
+ defaultTimeout: [300, []],
+ gatewayConfigurationJson: ['', []],
+ gatewayConfigurationName: ['', []],
+ gatewayConfiguration: ['', []],
+ defaultIdentityType: ['', []],
+ defaultDeviceType: ['', []],
+ description: ['', []],
});
- this._httpClient.get('api/produce/get/' + this.id).pipe(
- map(x => {
- this.form.patchValue(this.data);
- })
- ).subscribe();
+ if (this.id != Guid.EMPTY) {
+ this._httpClient.get('api/produces/get?id=' + this.id).pipe(
+ map(x => {
+ this.form.patchValue(x.data);
+
+ if (x.data.gatewayType === 'Customize') {
+ this.form.patchValue({ gatewayConfigurationJson: this.form.value.gatewayConfiguration });
+ } else if (x.data.gatewayType === 'Unknow') {
+ this.form.patchValue({ gatewayConfigurationName: '' });
+ this.form.patchValue({ gatewayConfigurationJson: '' });
+
+ } else {
+ this.form.patchValue({ gatewayConfigurationName: this.form.value.gatewayConfiguration });
+ }
-
-
+
+ })
+ ).subscribe();
+ }
}
submit() {
this.submitting = true;
-
+ if (this.form.value.gatewayType === 'Customize') {
+ this.form.patchValue({ gatewayConfiguration: this.form.value.gatewayConfigurationJson });
+ } else if (this.form.value.gatewayType === 'Unknow') {
+ this.form.patchValue({ gatewayConfiguration: '' });
+ } else {
+ this.form.patchValue({ gatewayConfiguration: this.form.value.gatewayConfigurationName });
+ }
if (this.id == Guid.EMPTY) {
- this._httpClient.post('api/produce', this.form.value).subscribe(
- () => {
- this.submitting = false;
- this.msg.create('success', '产品新增成功');
- this.close();
- },
- () => {
- this.msg.create('error', '产品新增失败');
- this.close();
- },
- () => {}
+ this._httpClient.post('api/produces/save', this.form.value).subscribe(
+ {
+
+ next: next => {
+ this.submitting = false;
+
+ if (next.code === 10000) {
+ this.msg.create('success', '产品新增成功');
+ this.close();
+ }
+
+ },
+ error: error => {
+ this.msg.create('error', '产品新增失败');
+ this.close();
+ },
+ complete: () => { }
+
+ }
);
} else {
- this._httpClient.put('api/produce/' + this.id, this.form.value).subscribe(
- () => {
- this.submitting = false;
- this.msg.create('success', '产品修改成功');
- this.close();
- },
- () => {
- this.msg.create('error', '产品修改失败');
- this.close();
- },
- () => {}
+ this._httpClient.put('api/produces/update', this.form.value).subscribe(
+
+ {
+ next: next => {
+ this.submitting = false;
+ if (next.code === 10000) {
+ this.msg.create('success', '产品修改成功');
+ this.close();
+ }
+ },
+ error: error => {
+ this.msg.create('error', '产品修改失败');
+ this.close();
+ },
+ complete: () => { }
+
+ }
+
);
}
}
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producelist/producelist.component.html b/IoTSharp/ClientApp/src/app/routes/produce/producelist/producelist.component.html
index a80b5c67c6fbc0484347bb3cef0a5180e9cae6b3..a3352ac8ff6d0d9bf4a4074127cc6c37ae11b79a 100644
--- a/IoTSharp/ClientApp/src/app/routes/produce/producelist/producelist.component.html
+++ b/IoTSharp/ClientApp/src/app/routes/produce/producelist/producelist.component.html
@@ -35,8 +35,14 @@
{{ 'button.new' | translate }}
-->
-
-
+
+
+
+
+
+
+
+
diff --git a/IoTSharp/ClientApp/src/app/routes/produce/producelist/producelist.component.ts b/IoTSharp/ClientApp/src/app/routes/produce/producelist/producelist.component.ts
index 9c7f5a85a680b10ecfe04940397125a46a38f76d..1620da045fa452cba64610b29873c07c5835a9df 100644
--- a/IoTSharp/ClientApp/src/app/routes/produce/producelist/producelist.component.ts
+++ b/IoTSharp/ClientApp/src/app/routes/produce/producelist/producelist.component.ts
@@ -1,11 +1,13 @@
import { ChangeDetectorRef, Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
-import { STPage, STReq, STRes, STComponent, STColumn, STData } from '@delon/abc/st';
+import { STPage, STReq, STRes, STComponent, STColumn, STData, STChange, STColumnTag, STColumnBadge } from '@delon/abc/st';
import { ModalHelper, SettingsService, _HttpClient } from '@delon/theme';
import { Guid } from 'guid-typescript';
import { NzDrawerService } from 'ng-zorro-antd/drawer';
import { NzMessageService } from 'ng-zorro-antd/message';
import { appmessage } from 'src/app/models/appmessage';
+import { ProducedatadictionaryformComponent } from '../producedatadictionaryform/producedatadictionaryform.component';
+import { ProducedataformComponent } from '../producedataform/producedataform.component';
import { ProduceformComponent } from '../produceform/produceform.component';
@Component({
@@ -66,8 +68,8 @@ export class ProducelistComponent implements OnInit {
}
];
- url = 'api/produce/list';
- req: STReq = { method: 'POST', allInBody: true, reName: { pi: 'offset', ps: 'limit' }, params: this.q };
+ url = 'api/produces/list';
+ req: STReq = { method: 'GET', allInBody: true, reName: { pi: 'offset', ps: 'limit' }, params: this.q };
// 定义返回的参数
res: STRes = {
@@ -76,6 +78,36 @@ export class ProducelistComponent implements OnInit {
list: 'data.rows'
}
};
+ BADGE: STColumnBadge = {
+ true: { text: '在线', color: 'success' },
+ false: { text: '离线', color: 'error' }
+ };
+ TAG: STColumnTag = {
+ AccessToken: { text: 'AccessToken', color: 'green' },
+ X509Certificate: { text: 'X509Certificate', color: 'blue' }
+ };
+
+ DeviceTAG: STColumnTag = {
+ Device: { text: '设备', color: 'green' },
+ Gateway: { text: '网关', color: 'blue' }
+ };
+ devicecolumns:STColumn[] = [
+
+ { title: 'id', index: 'id', },
+ {title: '名称',
+ index: 'name',
+ render: 'name',
+ type: 'link',
+
+
+ },
+ { title: '设备类型', index: 'deviceType', type: 'tag', tag: this.DeviceTAG },
+ { title: '在线状态', index: 'active', type: 'badge', badge: this.BADGE, sort: true },
+ { title: '最后活动时间', index: 'lastActivityDateTime', type: 'date' },
+ { title: '认证方式', index: 'identityType', type: 'tag', tag: this.TAG},
+
+
+ ]
@ViewChild('st', { static: true })
st!: STComponent;
@@ -106,7 +138,21 @@ export class ProducelistComponent implements OnInit {
this.openComponent(item.id);
}
},
-
+ {
+ text: '属性',
+ // i18n: 'common.edit',
+ acl: 56,
+ click: (item: any) => {
+ this.editattr(item.id);
+ }
+ }, {
+ text: '字典',
+ // i18n: 'common.edit',
+ acl: 56,
+ click: (item: any) => {
+ this.editdic(item.id);
+ }
+ },
{
text: '删除',
pop: {
@@ -125,7 +171,7 @@ export class ProducelistComponent implements OnInit {
selectedRows: STData[] = [];
ngOnInit() {
-
+
}
openComponent(id: string): void {
var { nzMaskClosable, width } = this.settingService.getData('drawerconfig');
@@ -142,6 +188,88 @@ export class ProducelistComponent implements OnInit {
drawerRef.afterOpen.subscribe(() => { });
+ drawerRef.afterClose.subscribe(data => {
+ if (typeof data === 'string') {
+ }
+ this.getData();
+ });
+ }
+
+
+
+ editattr(id: string): void {
+ var { nzMaskClosable, width } = this.settingService.getData('drawerconfig');
+ var title = '属性编辑';
+ const drawerRef = this.drawerService.create({
+ nzTitle: title,
+ nzContent: ProducedataformComponent,
+ nzWidth: width,
+ nzMaskClosable: nzMaskClosable,
+ nzContentParams: {
+ id: id
+ }
+ });
+
+ drawerRef.afterOpen.subscribe(() => { });
+
+ drawerRef.afterClose.subscribe(data => {
+ if (typeof data === 'string') {
+ }
+
+ this.getData();
+ });
+ }
+ onchange($events: STChange): void {
+ switch ($events.type) {
+ case 'expand':
+ if ($events.expand.expand) {
+
+
+
+ }
+ break;
+
+ }
+
+ }
+
+
+
+
+ getdevices() {
+
+ this.http.post('', {}).subscribe({
+ next: next => {
+
+ }, error: error => {
+
+ }, complete: () => {
+
+ }
+
+ })
+
+
+
+
+ }
+
+
+ editdic(id: string): void {
+ var { nzMaskClosable, width } = this.settingService.getData('drawerconfig');
+ var title = '字典编辑';
+ const drawerRef = this.drawerService.create({
+ nzTitle: title,
+ nzContent: ProducedatadictionaryformComponent,
+ nzWidth: "100%",
+ nzMaskClosable: nzMaskClosable,
+ nzContentParams: {
+ id: id
+ }
+ });
+
+ drawerRef.afterOpen.subscribe(() => { });
+
drawerRef.afterClose.subscribe(data => {
if (typeof data === 'string') {
}
@@ -150,23 +278,17 @@ export class ProducelistComponent implements OnInit {
});
}
- r;
getData() {
this.st.req = this.req;
this.st.load(1);
}
delete(id: number) {
- this.http.get('api/produce/delete?id=' + id).subscribe(() => {
+ this.http.get('api/produces/delete?id=' + id).subscribe(() => {
this.st.load(this.st.pi);
});
}
- setstatus(id: number) {
- this.http.get('api/produce/setstatus?id=' + id).subscribe(() => {
- this.st.load(this.st.pi);
- });
- }
add(tpl: TemplateRef<{}>) { }
diff --git a/IoTSharp/ClientApp/src/app/routes/routes-routing.module.ts b/IoTSharp/ClientApp/src/app/routes/routes-routing.module.ts
index 8619f96ab10af6dfd328ee8716d5b31672b7195d..2f2f65f1f40ad71e66200ae3083a43075c4754d3 100644
--- a/IoTSharp/ClientApp/src/app/routes/routes-routing.module.ts
+++ b/IoTSharp/ClientApp/src/app/routes/routes-routing.module.ts
@@ -39,6 +39,7 @@ const routes: Routes = [
children: [
{ path: 'assets', loadChildren: () => import('./assets/assets.module').then(m => m.AssetsModule) },
{ path: 'devices', loadChildren: () => import('./devices/devices.module').then(m => m.DevicesModule) },
+ { path: 'produce', loadChildren: () => import('./produce/produce.module').then(m => m.ProduceModule) },
{ path: 'settings', loadChildren: () => import('./settings/settings.module').then(m => m.SettingsModule) },
{ path: 'alarms', loadChildren: () => import('./alarms/alarms.module').then(m => m.AlarmsModule) },
{ path: 'rules', loadChildren: () => import('./rules/rules.module').then(m => m.RulesModule) }
diff --git a/IoTSharp/ClientApp/src/style-icons.ts b/IoTSharp/ClientApp/src/style-icons.ts
index 11785b4fa742d5f50ecddcdbea4dbe4581ccb5c5..f2574b903e297dcb9cfa10173d9f2b624afdf86c 100644
--- a/IoTSharp/ClientApp/src/style-icons.ts
+++ b/IoTSharp/ClientApp/src/style-icons.ts
@@ -12,7 +12,9 @@ import {
AlertOutline,
GoldFill,
GoldTwoTone,
- GoldOutline
+ GoldOutline,
+ SaveOutline,
+ MedicineBoxOutline
} from '@ant-design/icons-angular/icons';
export const ICONS = [
@@ -27,5 +29,7 @@ export const ICONS = [
AlertOutline,
GoldFill,
GoldTwoTone,
- GoldOutline
+ GoldOutline,
+ SaveOutline,
+ MedicineBoxOutline
];
diff --git a/IoTSharp/Controllers/MenuController.cs b/IoTSharp/Controllers/MenuController.cs
index 5c51a7f819748a5be1f6533ea598c223fd5883b9..5069037671972994de6d30958f5b151bb554c9fe 100644
--- a/IoTSharp/Controllers/MenuController.cs
+++ b/IoTSharp/Controllers/MenuController.cs
@@ -87,7 +87,19 @@ namespace IoTSharp.Controllers
{
new { text = "用户列表", i18n = "", link = "/iot/settings/userlist" }
}
- }, new
+ },
+
+ new
+ {
+ text = "产品管理",
+ i18n = "",
+ icon = "medicinebox",
+ children = new[]
+ {
+ new { text = "产品列表", i18n = "", link = "/iot/produce/producelist" }
+ }
+ },
+ new
{
text = "设备管理",
i18n = "",
diff --git a/IoTSharp/Controllers/ProducesController.cs b/IoTSharp/Controllers/ProducesController.cs
index 0f69b48cb39f4fe270dc96af2ad256ebeb18d579..ef4385ef9b41884583eda3d9a07ea00b23bb41cd 100644
--- a/IoTSharp/Controllers/ProducesController.cs
+++ b/IoTSharp/Controllers/ProducesController.cs
@@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
+using Microsoft.Scripting.Utils;
using ShardingCore.Extensions;
namespace IoTSharp.Controllers
@@ -31,6 +32,7 @@ namespace IoTSharp.Controllers
_context = context;
_logger = logger;
}
+
///
/// 产品列表
///
@@ -49,16 +51,47 @@ namespace IoTSharp.Controllers
condition = condition.And(x => x.Name.Contains(m.Name));
}
- return new ApiResult>(ApiCode.Success, "OK", new PagedData
+
+ if (m.limit > 1)
+ {
+ return new ApiResult>(ApiCode.Success, "OK", new PagedData
+ {
+ total = await _context.Produces.CountAsync(condition),
+ rows = _context.Produces.Include(c=>c.Devices).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, Devices = c.Devices
+ }).ToList()
+
+ });
+
+ }
+ else
{
- 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()
+ return new ApiResult>(ApiCode.Success, "OK", new PagedData
+ {
+ total = await _context.Produces.CountAsync(),
+ rows = _context.Produces.Where(condition)
+ .ToList().Select(c => new ProduceDto
+ {
+ Id = c.Id,
+ DefaultIdentityType = c.DefaultIdentityType,
+ DefaultTimeout = c.DefaultTimeout,
+ Description = c.Description,
+ Name = c.Name
+ }).ToList()
- });
+ });
+ }
+
+
}
+
///
///
///
@@ -67,9 +100,11 @@ namespace IoTSharp.Controllers
[HttpGet]
public async Task>> 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>(ApiCode.Success, "OK", result);
}
+
///
/// 获取产品
///
@@ -84,10 +119,7 @@ namespace IoTSharp.Controllers
{
return new ApiResult(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,
@@ -105,6 +137,7 @@ namespace IoTSharp.Controllers
}
}
+
///
/// 删除产品
///
@@ -126,6 +159,7 @@ namespace IoTSharp.Controllers
await _context.SaveChangesAsync();
return new ApiResult(ApiCode.Success, "OK", true);
}
+
return new ApiResult(ApiCode.CantFindObject, "Produce is not found", false);
}
catch (Exception e)
@@ -140,7 +174,7 @@ namespace IoTSharp.Controllers
///
///
///
- [HttpGet]
+ [HttpPost]
public async Task> Save(ProduceAddDto dto)
{
@@ -151,14 +185,14 @@ namespace IoTSharp.Controllers
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=
+ 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;
+ produce.GatewayConfiguration = dto.GatewayConfiguration;
+ produce.Icon = dto.Icon;
+ produce.GatewayType = dto.GatewayType;
_context.Produces.Add(produce);
await _context.SaveChangesAsync();
return new ApiResult(ApiCode.Success, "OK", true);
@@ -175,7 +209,7 @@ namespace IoTSharp.Controllers
///
///
///
- [HttpGet]
+ [HttpPut]
public async Task> Update(ProduceAddDto dto)
{
@@ -184,23 +218,210 @@ namespace IoTSharp.Controllers
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.GatewayType = dto.GatewayType;
produce.GatewayConfiguration = dto.GatewayConfiguration;
produce.Name = dto.Name;
produce.Icon = dto.Icon;
_context.Produces.Update(produce);
await _context.SaveChangesAsync();
}
+
return new ApiResult(ApiCode.CantFindObject, "Produce is not found", false);
}
catch (Exception e)
{
return new ApiResult(ApiCode.Exception, e.Message, false);
}
-
+
+ }
+
+
+
+
+ ///
+ /// 获取产品属性
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetProduceData(Guid produceId)
+ {
+ var produce = await _context.Produces
+ .SingleOrDefaultAsync(c => c.Id == produceId);
+ if (produce != null)
+ {
+
+
+ //var result = _context.ProduceDatas.Where(c => c.Owner.Id == produceId).Select(c => new ProduceDataItemDto
+ //{ KeyName = c.KeyName, DataSide = c.DataSide, Type = c.Type }).ToList();
+ var result = _context.DataStorage.Where(c => c.DeviceId == Guid.Empty).Select(c =>
+ new ProduceDataItemDto
+ { KeyName = c.KeyName, DataSide = c.DataSide, Type = c.Type }).ToList();
+ return new ApiResult>(ApiCode.Success, "Ok", result);
+ }
+ return new ApiResult>(ApiCode.CantFindObject, "Produce is not found", null);
}
+
+
+
+
+ ///
+ /// 修改属性
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> EditProduceData(ProduceDataEditDto dto)
+ {
+
+ try
+ {
+ var produce = await _context.Produces.Include(c => c.DefaultAttributes).SingleOrDefaultAsync(c => c.Id == dto.produceId);
+ if (produce != null)
+ {
+ var pds = _context.ProduceDatas.Where(c => c.Owner == produce).ToList();
+ if (dto.ProduceData != null && dto.ProduceData.Length > 0)
+ {
+ var data = dto.ProduceData.Select(c => new ProduceData { KeyName = c.KeyName, DataSide = c.DataSide, Type = c.Type, Owner = produce, DateTime = DateTime.Now }).ToList();
+ foreach (var item in data)
+ {
+ var pd = pds.FirstOrDefault(c => c.KeyName.ToLower() == item.KeyName.ToLower());
+ if (pd != null)
+ {
+ pd.DataSide = item.DataSide;
+ pd.Type = item.Type;
+ _context.ProduceDatas.Update(pd);
+ }
+ else
+ {
+ _context.ProduceDatas.Add(item);
+ }
+ }
+ await _context.SaveChangesAsync();
+ var delete_keynames = pds.Select(c => c.KeyName.ToLower())
+ .Except(dto.ProduceData.Select(c => c.KeyName.ToLower())).ToArray();
+ if (delete_keynames.Length > 0)
+ {
+ var deleteattr = pds.Join(delete_keynames, x => x.KeyName.ToLower(), y => y, (x, y) => x).ToArray();
+ _context.ProduceDatas.RemoveRange(deleteattr);
+ await _context.SaveChangesAsync();
+
+ }
+
+ return new ApiResult(ApiCode.Success, "Ok", true);
+ }
+ return new ApiResult(ApiCode.CantFindObject, "Produce data is not found", false);
+ }
+ return new ApiResult(ApiCode.CantFindObject, "Produce is not found", false);
+ }
+ catch (Exception e)
+ {
+ return new ApiResult(ApiCode.Exception, e.Message, false);
+ }
+
+ }
+
+
+
+
+ ///
+ /// 获取产品字典
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task>> GetProduceDictionary(Guid produceId)
+ {
+ var produce = await _context.Produces.Include(c => c.Dictionaries)
+ .SingleOrDefaultAsync(c => c.Id == produceId);
+ if (produce != null)
+ {
+ return new ApiResult>(ApiCode.Success, "Ok", produce.Dictionaries);
+ }
+ return new ApiResult>(ApiCode.CantFindObject, "Produce is not found", null);
+ }
+
+
+ ///
+ /// 修改字典
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> EditProduceDictionary(ProduceDictionaryEditDto dto)
+ {
+
+
+ var profile = this.GetUserProfile();
+ try
+ {
+ var produce = await _context.Produces.Include(c => c.Dictionaries).SingleOrDefaultAsync(c => c.Id == dto.produceId);
+ if (produce != null)
+ {
+
+
+ foreach (var item in dto.ProduceDictionaryData)
+ {
+
+ if (item.Id == Guid.Empty)
+ {
+
+ var produceDictionary = new ProduceDictionary();
+ produceDictionary.KeyName = item.KeyName;
+ produceDictionary.DataType = item.DataType;
+ produceDictionary.Customer = profile.Customer;
+ produceDictionary.DefaultValue = item.DefaultValue;
+ produceDictionary.Display = item.Display;
+ produceDictionary.DisplayName = item.DisplayName;
+ produceDictionary.KeyDesc = item.KeyDesc;
+ produceDictionary.Tag = item.Tag;
+ produceDictionary.UnitConvert = item.UnitConvert;
+ produceDictionary.Unit = item.Unit;
+ produceDictionary.UnitExpression = item.UnitExpression;
+ produce.Dictionaries.Add(produceDictionary);
+ await _context.SaveChangesAsync();
+ }
+ else
+ {
+ var produceDictionary = await _context.ProduceDictionaries.SingleOrDefaultAsync(c => c.Id == item.Id);
+ if (produceDictionary != null)
+ {
+ produceDictionary.KeyName = item.KeyName;
+ produceDictionary.DataType = item.DataType;
+ produceDictionary.Customer = profile.Customer;
+ produceDictionary.DefaultValue = item.DefaultValue;
+ produceDictionary.Display = item.Display;
+ produceDictionary.DisplayName = item.DisplayName;
+ produceDictionary.KeyDesc = item.KeyDesc;
+ produceDictionary.Tag = item.Tag;
+ produceDictionary.UnitConvert = item.UnitConvert;
+ produceDictionary.Unit = item.Unit;
+ produceDictionary.UnitExpression = item.UnitExpression;
+ _context.ProduceDictionaries.Update(produceDictionary);
+ await _context.SaveChangesAsync();
+ }
+
+ }
+ }
+ var deletedic = produce.Dictionaries.Select(c => c.Id).Except(dto.ProduceDictionaryData.Select(c => c.Id)).ToList();
+ _context.ProduceDictionaries.RemoveRange(produce.Dictionaries.Where(c => deletedic.Any(p => p == c.Id)).ToList());
+ await _context.SaveChangesAsync();
+
+ return new ApiResult(ApiCode.Success, "Ok", true);
+ }
+ return new ApiResult(ApiCode.CantFindObject, "Produce is not found", false);
+ }
+ catch (Exception e)
+ {
+ return new ApiResult(ApiCode.Exception, e.Message, false);
+ }
+
+ }
+
+
+
}
}
diff --git a/IoTSharp/Dtos/ProduceAddDto.cs b/IoTSharp/Dtos/ProduceAddDto.cs
index 8f1a1ab01da3b20c77bd8cc1b608a7ec3df0e76f..af80a7a6bef93f39f81590417c4283d613342a96 100644
--- a/IoTSharp/Dtos/ProduceAddDto.cs
+++ b/IoTSharp/Dtos/ProduceAddDto.cs
@@ -24,6 +24,7 @@ namespace IoTSharp.Dtos
///
/// 网关类型 根据不通网关来处理相关配置
///
+ [EnumDataType(typeof(GatewayType))]
public GatewayType GatewayType { get; set; } = GatewayType.Unknow;
///
diff --git a/IoTSharp/Dtos/ProduceDataEditDto.cs b/IoTSharp/Dtos/ProduceDataEditDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4bc16019fe08e3b70e8ee81ac67cf9d2b80961e6
--- /dev/null
+++ b/IoTSharp/Dtos/ProduceDataEditDto.cs
@@ -0,0 +1,25 @@
+using System;
+using IoTSharp.Contracts;
+
+namespace IoTSharp.Dtos
+{
+
+
+
+ public class ProduceDataEditDto
+ {
+ public Guid produceId { get; set; }
+ public ProduceDataItemDto[] ProduceData { get; set; }
+ }
+
+
+
+ public class ProduceDataItemDto
+ {
+ public string KeyName { get; set; }
+ public DataSide DataSide { get; set; }
+ public DataType Type { get; set; }
+
+ }
+
+}
diff --git a/IoTSharp/Dtos/ProduceDictionaryEditDto.cs b/IoTSharp/Dtos/ProduceDictionaryEditDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..90cdb911eeaad1b5cc3f0309f8f47b61f6e240a8
--- /dev/null
+++ b/IoTSharp/Dtos/ProduceDictionaryEditDto.cs
@@ -0,0 +1,91 @@
+using System;
+using IoTSharp.Contracts;
+
+namespace IoTSharp.Dtos
+{
+
+
+
+
+ public class ProduceDictionaryEditDto
+ {
+ public Guid produceId { get; set; }
+ public ProduceDictionaryItemDto[] ProduceDictionaryData { get; set; }
+ }
+
+
+
+ public class ProduceDictionaryItemDto
+ {
+
+ public Guid Id { get; set; }
+
+ ///
+ /// 字段名称
+ ///
+ public string KeyName { get; set; }
+
+ ///
+ /// 字段显示名称
+ ///
+ public string DisplayName { get; set; }
+
+
+
+ ///
+ /// 单位
+ ///
+ public string Unit { get; set; }
+
+ ///
+ /// 单位转换表达式
+ ///
+ public string UnitExpression { get; set; }
+
+ ///
+ ///
+ ///
+ public bool UnitConvert { get; set; }
+ ///
+ /// 字段备注
+ ///
+ public string? KeyDesc { get; set; }
+ ///
+ /// 默认值
+ ///
+ public string? DefaultValue { get; set; }
+
+ ///
+ /// 是否显示
+ ///
+ public bool Display { get; set; }
+
+ ///
+ /// 位置名称
+ ///
+ public string Place0 { get; set; }
+ ///
+ /// 此位置顺序
+ ///
+ public string PlaceOrder0 { get; set; }
+ public string Place1 { get; set; }
+ public string PlaceOrder1 { get; set; }
+ public string Place2 { get; set; }
+ public string PlaceOrder2 { get; set; }
+ public string Place3 { get; set; }
+ public string PlaceOrder3 { get; set; }
+ public string Place4 { get; set; }
+ public string PlaceOrder4 { get; set; }
+ public string Place5 { get; set; }
+ public string PlaceOrder5 { get; set; }
+ ///
+ /// 数据类型
+ ///
+ public DataType DataType { get; set; }
+
+
+ public string? Tag { get; set; }
+
+ }
+
+}
diff --git a/IoTSharp/Dtos/ProduceDto.cs b/IoTSharp/Dtos/ProduceDto.cs
index 4c39ef46a3ace850907aba22bdceee3a4ad46846..f6de973886ad2fba20140ff7bf8fe066a0700165 100644
--- a/IoTSharp/Dtos/ProduceDto.cs
+++ b/IoTSharp/Dtos/ProduceDto.cs
@@ -21,5 +21,8 @@ namespace IoTSharp.Dtos
public IdentityType DefaultIdentityType { get; set; } = IdentityType.AccessToken;
public string Description { get; set; }
+
+ public List Devices { get; set; }
+
}
}
diff --git a/IoTSharp/IoTSharp.xml b/IoTSharp/IoTSharp.xml
index a3addda38e0601bf9e114e7e647d51d9608f8523..928746b495dd8256b10f00ea6eccd20f5ab7f633 100644
--- a/IoTSharp/IoTSharp.xml
+++ b/IoTSharp/IoTSharp.xml
@@ -556,6 +556,34 @@
+
+
+ 获取产品属性
+
+
+
+
+
+
+ 修改属性
+
+
+
+
+
+
+ 获取产品字典
+
+
+
+
+
+
+ 修改字典
+
+
+
+
更新节点的条件表达式
@@ -838,6 +866,61 @@
默认设备类型
+
+
+ 字段名称
+
+
+
+
+ 字段显示名称
+
+
+
+
+ 单位
+
+
+
+
+ 单位转换表达式
+
+
+
+
+
+
+
+
+
+ 字段备注
+
+
+
+
+ 默认值
+
+
+
+
+ 是否显示
+
+
+
+
+ 位置名称
+
+
+
+
+ 此位置顺序
+
+
+
+
+ 数据类型
+
+
查询历史遥测数据请求结构体
diff --git a/IoTSharp/Models/IPageParam.cs b/IoTSharp/Models/IPageParam.cs
index 2f41d4b7409e90b82b77ce69e0f21e8dbf51f3ec..1554149d38e3525029e66dd79dee1c9e29379c13 100644
--- a/IoTSharp/Models/IPageParam.cs
+++ b/IoTSharp/Models/IPageParam.cs
@@ -57,6 +57,7 @@ namespace IoTSharp.Controllers.Models
public bool OnlyActive { get; set; }
public string Name { get; set; }
+
}
public class RulePageParam : IPageParam