项目初始化

This commit is contained in:
Taric Xin
2021-11-26 16:34:35 +08:00
parent 66644bcf0a
commit 5287578452
354 changed files with 45736 additions and 0 deletions

View File

@ -0,0 +1,83 @@
<nz-drawer [(nzVisible)]="collapse" [nzPlacement]="dir === 'rtl' ? 'left' : 'right'" [nzWidth]="300"
(nzOnClose)="toggle()">
<div *nzDrawerContent class="setting-drawer__content">
<div class="setting-drawer__body">
<h3 class="setting-drawer__title">整体风格设置</h3>
<div class="setting-drawer__blockChecbox">
<div *ngFor="let t of themes" class="setting-drawer__blockChecbox-item" (click)="setLayout('theme', t.key)"
[nz-tooltip]="t.title">
<img src="{{ t.img }}" alt="{{ t.key }}" />
<div *ngIf="layout.theme === t.key" class="setting-drawer__blockChecbox-selectIcon">
<i nz-icon nzType="check"></i>
</div>
</div>
</div>
</div>
<div class="setting-drawer__body setting-drawer__theme">
<h3 class="setting-drawer__title">主题色</h3>
<span *ngFor="let c of colors" (click)="changeColor(c.color)" nz-tooltip="c.key" class="setting-drawer__theme-tag"
[ngStyle]="{ 'background-color': c.color }">
<i *ngIf="color === c.color" nz-icon nzType="check"></i>
</span>
</div>
<nz-divider></nz-divider>
<div class="setting-drawer__body">
<h3 class="setting-drawer__title">导航模式</h3>
<div class="setting-drawer__blockChecbox">
<div *ngFor="let t of menuModes" class="setting-drawer__blockChecbox-item" (click)="setLayout('menu', t.key)"
nz-tooltip="{{ t.title }}">
<img src="{{ t.img }}" alt="{{ t.key }}" />
<div *ngIf="layout.menu === t.key" class="setting-drawer__blockChecbox-selectIcon">
<i nz-icon nzType="check"></i>
</div>
</div>
</div>
<div class="setting-drawer__body-item">
内容区域宽度
<nz-select [(ngModel)]="layout.contentWidth" (ngModelChange)="setLayout('contentWidth', layout.contentWidth)"
nzSize="small">
<nz-option *ngFor="let i of contentWidths" [nzLabel]="i.title" [nzValue]="i.key" [nzDisabled]="i.disabled">
</nz-option>
</nz-select>
</div>
<div class="setting-drawer__body-item">
固定 Header
<nz-switch nzSize="small" [(ngModel)]="layout.fixedHeader"
(ngModelChange)="setLayout('fixedHeader', layout.fixedHeader)"></nz-switch>
</div>
<div class="setting-drawer__body-item" nz-tooltip="{{ !brand.fixedHeader ? '固定 Header 时可配置' : '' }}"
nzTooltipPlacement="left">
<span [style.opacity]="!brand.fixedHeader ? 0.5 : 1">下滑时隐藏 Header</span>
<nz-switch [nzDisabled]="!brand.fixedHeader" nzSize="small" [(ngModel)]="layout.autoHideHeader"
(ngModelChange)="setLayout('autoHideHeader', layout.autoHideHeader)"></nz-switch>
</div>
<div class="setting-drawer__body-item" nz-tooltip="{{ brand.menu === 'top' ? '侧边菜单布局时可配置' : '' }}"
nzTooltipPlacement="left">
<span [style.opacity]="brand.menu === 'top' ? 0.5 : 1">固定侧边菜单</span>
<nz-switch [nzDisabled]="brand.menu === 'top'" nzSize="small" [(ngModel)]="layout.fixSiderbar"
(ngModelChange)="setLayout('fixSiderbar', layout.fixSiderbar)"></nz-switch>
</div>
<div class="setting-drawer__body-item" nz-tooltip="{{ brand.menu === 'top' ? '' : '顶部菜单布局时可配置' }}"
nzTooltipPlacement="left">
<span [style.opacity]="brand.menu !== 'top' ? 0.5 : 1">只显示图标</span>
<nz-switch [nzDisabled]="brand.menu !== 'top'" nzSize="small" [(ngModel)]="layout.onlyIcon"
(ngModelChange)="setLayout('onlyIcon', layout.onlyIcon)"></nz-switch>
</div>
</div>
<nz-divider></nz-divider>
<div class="setting-drawer__body">
<h3 class="setting-drawer__title">其他设置</h3>
<div class="setting-drawer__body-item">
色弱模式
<nz-switch nzSize="small" [(ngModel)]="layout.colorWeak"
(ngModelChange)="setLayout('colorWeak', layout.colorWeak)"></nz-switch>
</div>
</div>
<nz-divider></nz-divider>
<button (click)="copy()" type="button" nz-button nzBlock>拷贝设置</button>
<nz-alert class="mt-md" nzType="warning" nzMessage="配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改配置文件"></nz-alert>
</div>
</nz-drawer>
<div class="setting-drawer__handle" [ngClass]="{ 'setting-drawer__handle-opened': collapse }" (click)="toggle()">
<i nz-icon [nzType]="!collapse ? 'setting' : 'close'" class="setting-drawer__handle-icon"></i>
</div>

View File

@ -0,0 +1,240 @@
import { Direction, Directionality } from '@angular/cdk/bidi';
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, NgZone, OnDestroy, OnInit, Optional } from '@angular/core';
import { copy, LazyService } from '@delon/util';
import { NzMessageService } from 'ng-zorro-antd/message';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { BrandService } from '../pro.service';
import { ProLayout } from '../pro.types';
@Component({
selector: 'pro-setting-drawer',
templateUrl: './setting-drawer.component.html',
preserveWhitespaces: false,
host: {
'[class.setting-drawer]': 'true',
'[class.setting-drawer-rtl]': `dir === 'rtl'`
},
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProSettingDrawerComponent implements OnInit, OnDestroy {
private loadedLess = false;
private destroy$ = new Subject<void>();
get layout(): ProLayout {
return this.brand.layout;
}
collapse = false;
dir: Direction = 'ltr';
themes = [
{
key: 'dark',
title: '暗色菜单风格',
img: 'https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg'
},
{
key: 'light',
title: '亮色菜单风格',
img: 'https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg'
}
];
color = '#2F54EB';
colors = [
{
key: '薄暮',
color: '#F5222D'
},
{
key: '火山',
color: '#FA541C'
},
{
key: '日暮',
color: '#FAAD14'
},
{
key: '明青',
color: '#13C2C2'
},
{
key: '极光绿',
color: '#52C41A'
},
{
key: '拂晓蓝(默认)',
color: '#1890ff'
},
{
key: '极客蓝',
color: '#2F54EB'
},
{
key: '酱紫',
color: '#722ED1'
}
];
menuModes = [
{
key: 'side',
title: '侧边菜单布局',
img: 'https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg'
},
{
key: 'top',
title: '顶部菜单布局',
img: 'https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg'
}
];
contentWidths = [
{
key: 'fixed',
title: '定宽',
disabled: false
},
{
key: 'fluid',
title: '流式',
disabled: false
}
];
constructor(
public brand: BrandService,
private cdr: ChangeDetectorRef,
private msg: NzMessageService,
private lazy: LazyService,
private zone: NgZone,
@Inject(DOCUMENT) private doc: any,
@Optional() private directionality: Directionality
) {
this.setLayout('menu', this.brand.menu, false);
}
ngOnInit(): void {
this.dir = this.directionality.value;
this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction: Direction) => {
this.dir = direction;
this.cdr.detectChanges();
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
private loadLess(): Promise<void> {
if (this.loadedLess) {
return Promise.resolve();
}
return this.lazy
.loadStyle('./assets/color.less', 'stylesheet/less')
.then(() => {
const lessConfigNode = this.doc.createElement('script');
lessConfigNode.innerHTML = `
window.less = {
async: true,
env: 'production',
javascriptEnabled: true
};
`;
this.doc.body.appendChild(lessConfigNode);
})
.then(() => this.lazy.loadScript('https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js'))
.then(() => {
this.loadedLess = true;
});
}
private runLess(): void {
const { color, zone, msg, cdr: cd } = this;
const msgId = msg.loading(`正在编译主题!`, { nzDuration: 0 }).messageId;
setTimeout(() => {
zone.runOutsideAngular(() => {
this.loadLess().then(() => {
(window as any).less
.modifyVars({
[`@primary-color`]: color
})
.then(() => {
msg.success('成功');
msg.remove(msgId);
zone.run(() => cd.detectChanges());
});
});
});
}, 200);
}
toggle(): void {
this.collapse = !this.collapse;
}
changeColor(color: string): void {
this.color = color;
this.runLess();
}
setLayout(name: string, value: any, cd: boolean = true): void {
switch (name) {
case 'menu':
const isTop = value === 'top';
this.contentWidths.find(w => w.key === 'fixed')!.disabled = !isTop;
const newLayout = {
...this.brand.layout,
contentWidth: isTop ? 'fixed' : 'fluid',
onlyIcon: isTop,
collapsed: isTop && !this.brand.isMobile ? false : this.brand.layout.collapsed
};
this.brand.setLayout(newLayout);
break;
case 'fixedHeader':
this.brand.setLayout('autoHideHeader', false);
break;
default:
break;
}
this.brand.setLayout(name, value);
if (cd) {
setTimeout(() => {
// Re-render G2 muse be trigger window resize
window.dispatchEvent(new Event('resize'));
this.cdr.markForCheck();
});
}
}
copy(): void {
const { color, layout } = this;
const vars: { [key: string]: string } = {
[`@primary-color`]: color
};
const colorVars = Object.keys(vars)
.map(key => `${key}: ${vars[key]};`)
.join('\n');
const layoutVars = Object.keys(layout)
.filter(
key => ~['theme', 'menu', 'contentWidth', 'fixedHeader', 'autoHideHeader', 'fixSiderbar', 'colorWeak', 'onlyIcon'].indexOf(key)
)
.map(key => {
const value = layout[key];
if (typeof value === 'boolean') {
return ` ${key}: ${value},`;
} else {
return ` ${key}: '${value}',`;
}
})
.join('\n');
copy(
`在 [src/styles/theme.less] 配置以下:\n{{colorVars}}\n\n在 [src/environments/*] 的 pro 配置以下:\nexport const environment = {\n ...\n pro: {\n{{layoutVars}}\n }\n}`
);
this.msg.success(`拷贝成功,请根据剪切板内容进行替换`);
}
}