B站演示地址https://www.bilibili.com/video/bv1RV41177Gb
此文具体代码在文末语雀链接,需额外付费
https://www.bilibili.com/video/bv1RV41177Gb
说明:由于CE版没有权限功能,所以不能主题定制功能不能细分到每个用户一套主题。
本文实现的是:定制主题绑定租户,租户管理员和客户用户继承所属租户的主题,且租户管理员可修改主题;不同租户下的租户管理员和客户用户登录后分别显示自己的主题。这个效果在视频中有演示。
后面会发布关于登录界面的主题定制功能,可为每个租户设置专有域名和对应的登录界面。俩者结合就可以做到,对租户界面的特有定制,不同租户都拥有属于自己的UI界面。
ngrx/store
angular canDeactivate
angular canDeactivate CSDN介绍
angular FormBuilder
angular FormGroup
Material Design 组件库 for Angular
material design icons
HasDirtyFlag
接口,并定义isDirty
变量,值为true
显示未保存提示,false
不显示。自己根据表单控制。详细代码在文末。添加下面的代码即可实现此功能。
为减少文章篇幅,优化阅读体验,代码请滚动查看。
内容确实有点多,如果发现有整理遗漏的地方,请联系告知。
ui-ngx/src/app/modules/home/pages/custom-ui/下新建
custom-ui.component.ts
import { AfterViewInit, Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { environment as env } from '@env/environment';
import { TranslateService } from '@ngx-translate/core';
import { DashboardService } from '@core/http/dashboard.service';
import { UIInfo } from '@shared/models/dashboard.models';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { ActionTenantUIChangeAll } from '@core/ui/tenant-ui.actions';
import { HasDirtyFlag } from '@core/guards/confirm-on-exit.guard';
import { TenantUIState } from '@core/ui/tenant-ui.models';
import { PageComponent } from '@shared/components/page.component';
import { initialState } from '@core/ui/tenant-ui.reducer';
@Component({
selector: 'tb-custom-ui',
templateUrl: './custom-ui.component.html',
styleUrls: ['./custom-ui.component.scss']
})
export class CustomUiComponent extends PageComponent implements OnInit, HasDirtyFlag,AfterViewInit {
isDirty = false;
faviconMaxKBytes = 256;
logoMaxKBytes = 4096;
customUiFormGroup: FormGroup;
initData: any;
previousData: any;
constructor(
protected store: Store<AppState>,
private translate: TranslateService,
private dashboardService: DashboardService,
private fb: FormBuilder
) {
super(store);
this.initForm();
this.writeFormByHttp();
}
ngAfterViewInit() {
}
ngOnInit(): void {
this.customUiFormGroup.valueChanges.subscribe(data => {
Reflect.ownKeys(data).forEach(key => data[key.toString()] = data[key.toString()] === '' ? null : data[key.toString()]);
if(JSON.stringify(this.initData) !== JSON.stringify(data)){
this.isDirty = true;
this.previousData = data;
this.store.dispatch(new ActionTenantUIChangeAll(data));
}else{
this.isDirty = false;
if(JSON.stringify(this.previousData) !== JSON.stringify(data)){
this.store.dispatch(new ActionTenantUIChangeAll(data));
}
}
});
}
writeFormByHttp() {
this.dashboardService.getTenantUIInfo().subscribe(ui => {
this.patchFormValue(ui);
this.initData = this.customUiFormGroup.value;
this.previousData = this.customUiFormGroup.value;
});
}
patchFormValue(ui: UIInfo | TenantUIState) {
this.customUiFormGroup.get('applicationTitle').patchValue(ui.applicationTitle);
this.customUiFormGroup.get('iconImageUrl').patchValue(ui.iconImageUrl);
this.customUiFormGroup.get('logoImageUrl').patchValue(ui.logoImageUrl);
this.customUiFormGroup.get('logoImageHeight').patchValue(ui.logoImageHeight);
this.customUiFormGroup.get('platformMainColor').patchValue(ui.platformMainColor);
this.customUiFormGroup.get('platformTextMainColor').patchValue(ui.platformTextMainColor);
this.customUiFormGroup.get('platformButtonColor').patchValue(ui.platformButtonColor);
this.customUiFormGroup.get('platformMenuColorActive').patchValue(ui.platformMenuColorActive);
this.customUiFormGroup.get('platformMenuColorHover').patchValue(ui.platformMenuColorHover);
this.customUiFormGroup.get('showNameVersion').patchValue(ui.showNameVersion);
this.customUiFormGroup.get('platformName').patchValue(ui.platformName);
this.customUiFormGroup.get('platformVersion').patchValue(ui.platformVersion);
}
//恢复到tb原始设置
reset($event: Event) {
if ($event) {
$event.stopPropagation();
}
this.patchFormValue(initialState);
this.store.dispatch(new ActionTenantUIChangeAll(this.customUiFormGroup.value));
this.isDirty = true;
}
//撤销本次操作
cancel($event: Event) {
if ($event) {
$event.stopPropagation();
}
this.writeFormByHttp();
}
//初始化表单
initForm() {
this.customUiFormGroup = this.fb.group({
applicationTitle: [null, []],
iconImageUrl: [null, []],
logoImageUrl: [null, []],
logoImageHeight: [null, []],
platformMainColor: [null, []],
platformTextMainColor: [null, []],
platformButtonColor: [null, []],
platformMenuColorActive: [null, []],
platformMenuColorHover: [null, []],
showNameVersion: [false, []],
platformName: [env.appTitle, []],
platformVersion: [env.tbVersion, []]
});
this.initData = this.customUiFormGroup.value;
this.previousData = this.customUiFormGroup.value;
}
submit($event: Event) {
if ($event) {
$event.stopPropagation();
}
this.dashboardService.saveTenantUIInfo(this.customUiFormGroup.value as UIInfo).subscribe(res => {
});
this.store.dispatch(new ActionTenantUIChangeAll(this.customUiFormGroup.value));
this.isDirty = false;
}
formatSlider(value: number) {
return value + 'px';
}
// advancedCssClick() {
//
// }
}
custom-ui.component.scss
@media screen and (min-width: 1280px){
.mat-card.settings-card {
width: 60%;
}
}
.mat-card.settings-card {
margin: .5rem;
}
.mat-headline{
font: 400 1.5rem/2rem Roboto,Helvetica Neue,sans-serif;
letter-spacing: normal;
margin: 0 0 1rem;
}
.mat-card-content{
padding-top: 1rem;
}
custom-ui.component.tml
后续内容在语雀文章添加主题设置功能