Skip to main content

设备模块

设备模块是一个非常有代表性的模块,可以说搞清楚设备就清楚了大部分模块的逻辑,本人是一名有7年Java服务开发经验的程序员 对前端并不熟悉,好在对数据结构及面向对象编程有较深的功底,对前端理解起来也比较快,下面就跟着我一起翻一翻前端设备模块的实现逻辑

模块目录

ui-ngx/src/app/modules/home/pages/device

模块入口

ui-ngx/src/app/modules/home/pages/device/device-routing.module.ts

const routes: Routes = [
{
path: 'devices',
data: {
breadcrumb: {
label: 'device.devices',
icon: 'devices_other'
}
},
children: [
{
path: '',
// 声明入口组件,table
component: EntitiesTableComponent,
data: {
// 权限
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER],
title: 'device.devices',
devicesType: 'tenant'
},
resolve: {
// 页面配置(你所看到的表格页面)
entitiesTableConfig: DevicesTableConfigResolver
}
},
{
path: ':entityId',
component: EntityDetailsPageComponent,
canDeactivate: [ConfirmOnExitGuard],
data: {
breadcrumb: {
labelFunction: entityDetailsPageBreadcrumbLabelFunction,
icon: 'devices_other'
} as BreadCrumbConfig<EntityDetailsPageComponent>,
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER],
title: 'device.devices',
devicesType: 'tenant'
},
resolve: {
entitiesTableConfig: DevicesTableConfigResolver
}
}
]
}
];

主页面配置(table)

@Injectable()
export class DevicesTableConfigResolver implements Resolve<EntityTableConfig<DeviceInfo>> {

private readonly config: EntityTableConfig<DeviceInfo> = new EntityTableConfig<DeviceInfo>();

private customerId: string;

constructor(
// @ngrx/store是基于RxJS的状态管理库
private store: Store<AppState>,
private broadcast: BroadcastService,
// 设备服务:提供了设备的API
private deviceService: DeviceService,
// 客户服务API
private customerService: CustomerService,
// 弹出框服务API
private dialogService: DialogService,
// 边缘服务API
private edgeService: EdgeService,
private homeDialogs: HomeDialogsService,
// 多国语言
private translate: TranslateService,
private datePipe: DatePipe,
private router: Router,
private dialog: MatDialog) {

// 当前表格实体类型:设备
this.config.entityType = EntityType.DEVICE;
// 左侧弹出窗的第一个页面:设备详细信息
this.config.entityComponent = DeviceComponent;
// 左侧弹出窗中的tabs
this.config.entityTabsComponent = DeviceTabsComponent;
// 多国语言
this.config.entityTranslations = entityTypeTranslations.get(EntityType.DEVICE);
// 帮助
this.config.entityResources = entityTypeResources.get(EntityType.DEVICE);

this.config.addDialogStyle = {width: '600px'};

this.config.deleteEntityTitle = device => this.translate.instant('device.delete-device-title', {deviceName: device.name});
this.config.deleteEntityContent = () => this.translate.instant('device.delete-device-text');
this.config.deleteEntitiesTitle = count => this.translate.instant('device.delete-devices-title', {count});
this.config.deleteEntitiesContent = () => this.translate.instant('device.delete-devices-text');

// 选择设备时加载设备信息
this.config.loadEntity = id => this.deviceService.getDeviceInfo(id.id);
// 保存设备信息
this.config.saveEntity = device => {
return this.deviceService.saveDevice(device).pipe(
tap(() => {
this.broadcast.broadcast('deviceSaved');
}),
mergeMap((savedDevice) => this.deviceService.getDeviceInfo(savedDevice.id.id)
));
};
// 配置右侧弹出框:打开详情页、公开、分配给客户、管理凭证、删除设备按钮的事件
this.config.onEntityAction = action => this.onDeviceAction(action, this.config);
this.config.detailsReadonly = () =>
(this.config.componentsData.deviceScope === 'customer_user' || this.config.componentsData.deviceScope === 'edge_customer_user');

this.config.headerComponent = DeviceTableHeaderComponent;

}

/**
* resolve
* 比如默认登录要求跳转到A页面,如果A的页面中表格数据是空则要求登录后要直接跳转到B页面。
* 如果在pageA的组件中的ngInit中判断,你会先看到pageA然后再跳到pageB,这样用户体验不太好。
* 这就要求在路由变化发生之前就要拿到后台返回的数据。这个时候我们可以使用Resolve
*/
resolve(route: ActivatedRouteSnapshot): Observable<EntityTableConfig<DeviceInfo>> {
const routeParams = route.params;
this.config.componentsData = {
deviceScope: route.data.devicesType,
deviceProfileId: null,
deviceCredentials$: new Subject<DeviceCredentials>(),
edgeId: routeParams.edgeId
};
this.customerId = routeParams.customerId;
this.config.componentsData.edgeId = routeParams.edgeId;

// https://www.jianshu.com/p/e83973caada2 只能帮到你这里了
return this.store.pipe(select(selectAuthUser), take(1)).pipe(
tap((authUser) => {
if (authUser.authority === Authority.CUSTOMER_USER) {
if (route.data.devicesType === 'edge') {
this.config.componentsData.deviceScope = 'edge_customer_user';
} else {
this.config.componentsData.deviceScope = 'customer_user';
}
this.customerId = authUser.customerId;
}
}),
mergeMap(() =>
this.customerId ? this.customerService.getCustomer(this.customerId) : of(null as Customer)
),
map((parentCustomer) => {
if (parentCustomer) {
if (parentCustomer.additionalInfo && parentCustomer.additionalInfo.isPublic) {
this.config.tableTitle = this.translate.instant('customer.public-devices');
} else {
this.config.tableTitle = parentCustomer.title + ': ' + this.translate.instant('device.devices');
}
} else if (this.config.componentsData.deviceScope === 'edge') {
this.edgeService.getEdge(this.config.componentsData.edgeId).subscribe(
edge => this.config.tableTitle = edge.name + ': ' + this.translate.instant('device.devices')
);
} else {
this.config.tableTitle = this.translate.instant('device.devices');
}
this.config.columns = this.configureColumns(this.config.componentsData.deviceScope);
this.configureEntityFunctions(this.config.componentsData.deviceScope);
this.config.cellActionDescriptors = this.configureCellActions(this.config.componentsData.deviceScope);
this.config.groupActionDescriptors = this.configureGroupActions(this.config.componentsData.deviceScope);
this.config.addActionDescriptors = this.configureAddActions(this.config.componentsData.deviceScope);
this.config.addEnabled = !(this.config.componentsData.deviceScope === 'customer_user' || this.config.componentsData.deviceScope === 'edge_customer_user');
this.config.entitiesDeleteEnabled = this.config.componentsData.deviceScope === 'tenant';
this.config.deleteEnabled = () => this.config.componentsData.deviceScope === 'tenant';
return this.config;
})
);
}
// 省略具体实现逻辑
}

表格数据

ui-ngx/src/app/core/http/entity.service.ts

   // 所有的实体类型数据都是根据这个函数中entityType来决定的,通过源码不难发现它是通过switch来控制的
private getEntitiesByPageLinkObservable(entityType: EntityType, pageLink: PageLink, subType: string = '',
config?: RequestConfig)

Tab

  • 页面:ui-ngx/src/app/modules/home/pages/device/device-tabs.component.html

配图:

设备详情信息

  • 页面:ui-ngx/src/app/modules/home/pages/device/device.component.html

配图:

更新菜单

ui-ngx/src/app/core/services/menu.service.ts