This commit is contained in:
Taric Xin
2022-01-20 17:27:41 +08:00
parent 3a0ae6a54e
commit 121fcce44c
22 changed files with 727 additions and 215 deletions

View File

@ -7,14 +7,9 @@
[button]="'none'"></sf>
</div>
<div nz-col [nzSpan]="8" nzOffset="1">
<button nz-button nzType="primary" [nzLoading]="service.http.loading" (click)="st?.load(1)">查询</button>
<button nz-button nzType="primary" [nzLoading]="service.http.loading"
(click)="loadMemu(selectedPlatform.appId)">查询</button>
<button nz-button (click)="resetSF()">重置</button>
<button nz-button (click)="menuImport(0)" [nzLoading]="service.http.loading">
导入货主菜单
</button>
<button nz-button (click)="menuImport(1)" [nzLoading]="service.http.loading">
导入运营后台菜单
</button>
<!-- <button nz-button (click)="delMenu(0)" [nzLoading]="service.http.loading">
清空货主菜单
</button>
@ -34,7 +29,15 @@
<ng-template #extraTemplate>
<div class="d-flex align-items-center">
<div>
<button nz-button nzType="primary" (click)="roleAction()">新增</button>
<button nz-button nzType="primary" (click)="menuAction('新增菜单')">新增</button>
<button nz-button nzType="primary" (click)="menuImport(0)" [disabled]="service.http.loading"
*ngIf="selectedPlatform.enName==='tms-smc-web'">
导入货主菜单
</button>
<button nz-button nzType="primary" (click)="menuImport(1)" [disabled]="service.http.loading"
*ngIf="selectedPlatform.enName==='tms-obc-web'">
导入运营后台菜单
</button>
</div>
</div>
</ng-template>
@ -47,40 +50,44 @@
{{ item.description }}
</ng-template>
</st> -->
<nz-table #expandTable [nzData]="listOfMapData" nzTableLayout="fixed" nzBordered>
<nz-table #expandTable [nzData]="listOfMapData" nzTableLayout="fixed" nzBordered nzSize="small"
[nzLoading]="service.http.loading">
<thead>
<tr>
<!-- <th nzWidth="70px" nzAlign="center">#</th> -->
<th>菜单名称</th>
<th>菜单编号</th>
<th>路由地址</th>
<th>菜单图标</th>
<th>菜单排序</th>
<th class="text-center">操作</th>
<th nzAlign="center" nzWidth="120px">菜单图标</th>
<th nzWidth="100px">菜单排序</th>
<th nzAlign="center">操作</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let data of expandTable.data">
<ng-container *ngFor="let item of mapOfExpandedData[data.key]">
<ng-container *ngFor="let item of mapOfExpandedData[data.key];let i = index">
<tr *ngIf="(item.parent && item.parent.expand) || !item.parent">
<!-- <td nzWidth="70px" nzAlign="center" [nzChecked]="item.checked">{{ i+1 }}</td> -->
<td [nzIndentSize]="item.level! * 20" [nzShowExpand]="!!item.children" [(nzExpand)]="item.expand"
(nzExpandChange)="collapse(mapOfExpandedData[data.key], item, $event)">
(nzExpandChange)="service.collapse(mapOfExpandedData[data.key], item, $event)">
{{ item.text }}
</td>
<td>{{ item.keyCode }}</td>
<td>{{ item.link }}</td>
<td>
<td nzAlign="center" nzWidth="120px">
<i nz-icon [nzType]="item.iconType"></i>
</td>
<td>{{ item.sorted }}</td>
<td class="text-center">
<a>查看</a>
<td nzWidth="100px">{{ item.sorted }}</td>
<td nzAlign="center">
<a (click)="menuAction('查看菜单',item,item.parentId,true)">查看</a>
<nz-divider nzType="vertical"></nz-divider>
<a>编辑</a>
<a (click)="menuAction('编辑菜单',item,item.parentId)">编辑</a>
<nz-divider nzType="vertical"></nz-divider>
<a>删除</a>
<a (click)="deleteAction(item)">删除</a>
<ng-container *ngIf="item.level!==3">
<nz-divider nzType="vertical"></nz-divider>
<a>新增子项</a>
<a (click)="menuAction('新增菜单',null,item.id)">新增子项</a>
</ng-container>
</td>
</tr>
</ng-container>

View File

@ -7,6 +7,7 @@ import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzModalService } from 'ng-zorro-antd/modal';
import { SettingRoleEditComponent } from 'src/app/routes/sys-setting/components/role-management/edit/edit.component';
import { MenuManagerService } from './../../services/menu-manager.service';
import { MenuModalComponent } from './menu-modal/menu-modal.component';
@Component({
selector: 'app-menu-manager-components-index',
@ -15,18 +16,11 @@ import { MenuManagerService } from './../../services/menu-manager.service';
})
export class MenuManagerComponentsIndexComponent implements OnInit {
selectedPlatform!: { name: string; appId: string; enName: string };
menus: Array<any> = [];
platforms: Array<any> = [];
currentSelectedNode: any;
transferData!: string;
dropType = {
dropPrev: true,
dropNext: true,
dropInner: true
};
platforms: Array<any> = [
{ name: '货主PC', appId: 'A48F72F0A304427F921794BAD86B3522', enName: 'tms-smc-web' },
{ name: '运营后台', appId: this.envSrv.env.appId, enName: 'tms-obc-web' }
];
@ViewChild('st', { static: true })
st!: STComponent;
@ViewChild('sf', { static: false })
sf!: SFComponent;
@ -34,14 +28,12 @@ export class MenuManagerComponentsIndexComponent implements OnInit {
properties: {
roleName: {
type: 'string',
title: '角色名称',
title: '菜单名称',
ui: { placeholder: '请输入' }
}
}
};
selectedRows: any[] = [];
mapOfExpandedData: { [key: string]: any[] } = {};
listOfMapData: any[] = [];
constructor(private envSrv: EAEnvironmentService, public service: MenuManagerService, private modal: NzModalService) {
@ -51,10 +43,6 @@ export class MenuManagerComponentsIndexComponent implements OnInit {
ngOnInit(): void {}
initData(): void {
this.platforms = [
{ name: '货主PC', appId: 'A48F72F0A304427F921794BAD86B3522', enName: 'tms-smc-web' },
{ name: '运营后台', appId: this.envSrv.env.appId, enName: 'tms-obc-web' }
];
this.selectedPlatform = this.platforms[0];
this.loadMemu(this.selectedPlatform.appId);
}
@ -64,115 +52,32 @@ export class MenuManagerComponentsIndexComponent implements OnInit {
if (res) {
this.listOfMapData = res;
this.listOfMapData.forEach(item => {
this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
this.mapOfExpandedData[item.key] = this.service.convertTreeToList(item);
});
console.log(this.listOfMapData, this.mapOfExpandedData);
}
});
}
platformChange(e: { name: string; appId: string }) {
if (e) {
this.loadMenus(e.appId);
} else {
this.menus = [];
this.currentSelectedNode = null;
}
}
loadMenus(appId: string) {
this.service.request(this.service.$api_get_one, { appId }, 'POST', false).subscribe(res => {
this.menus = res;
});
}
editValueChange(event: any) {}
menuImport(index: number) {
this.selectedPlatform = this.platforms[index];
if (!this.selectedPlatform) {
return;
}
this.service.http.request('GET', `assets/mocks/platform/${this.selectedPlatform.enName}.json`).subscribe((res: any) => {
this.addMenu(res.menu);
});
}
addMenu(menus: Array<Menu>, parentId: string = '') {
menus.forEach(r => {
if (parentId !== '') {
r.parentId = parentId;
}
this.service.request(this.service.$api_get_one, { appId: this.selectedPlatform.appId }, 'POST', false).subscribe(res => {
// 如果res.data存在则更新菜单
if (res.data) {
r.id = res.data.id;
}
this.service
.addOne({ appId: this.selectedPlatform.appId, ...r, isLeaf: !(r.children && r.children.length > 0) })
.subscribe(result => {
if (result) {
if (r.children && r.children.length > 0) {
this.addMenu(r.children, result.id);
}
}
});
});
});
// this.loadMenus(this.selectedPlatform.appId);
}
addMenuRecursion() {}
delMenu(type: number) {
this.modal.confirm({
nzTitle: '<i>删除确认</i>',
nzContent: `是否确认删除?`,
nzOnOk: () => {
this.getMenuByAppID(type === 0 ? 'A48F72F0A304427F921794BAD86B3522' : this.envSrv.env.appId);
}
});
}
getMenuByAppID(appId: string) {
this.service.request(this.service.$api_get_one, { appId }, 'POST', false).subscribe(res => {
if (res) {
const menus = res.data;
if (res.data?.length > 0) {
this.deleteMenuByAppID(res.data);
} else {
this.service.msgSrv.success('菜单已清空');
}
}
});
}
deleteMenuByAppID(arr: Array<any>) {
let ids: any[] = arr?.map(item => item.id) || [];
arr.forEach(item => {
if (item.children?.length > 0) {
this.deleteMenuByAppID(item.children);
}
});
this.service.request(this.service.$api_del_many, ids).subscribe(res => {});
}
changeMemu(key: number) {
this.selectedPlatform = this.platforms[key];
this.loadMemu(this.selectedPlatform.appId);
}
roleAction(item?: any) {
menuAction(nzTitle: string, item?: any, parentId?: string, isDisabled = false) {
const modal = this.modal.create({
nzContent: SettingRoleEditComponent,
nzTitle,
nzContent: MenuModalComponent,
nzWidth: 900,
nzComponentParams: item ? { i: { ...item } } : { i: { id: 0 } },
nzComponentParams: item
? { formData: { ...item }, isDisabled, params: { parentId, appId: this.selectedPlatform.appId } }
: { formData: { id: null }, params: { parentId, appId: this.selectedPlatform.appId } },
nzFooter: null
});
modal.afterClose.subscribe(res => {
this.st.load();
if (res) {
this.loadMemu(this.selectedPlatform.appId);
}
});
}
@ -182,12 +87,12 @@ export class MenuManagerComponentsIndexComponent implements OnInit {
nzClosable: false,
nzCancelText: '取消',
nzOnOk: () => {
// this.service.request(this.service.$api_dalete_role, [item.id]).subscribe(res => {
// if (res) {
// this.service.msgSrv.success('删除角色成功');
// this.st.load();
// }
// });
this.service.request(this.service.$api_del_many, [item.id]).subscribe(res => {
if (res) {
this.service.msgSrv.success('删除菜单成功');
this.loadMemu(this.selectedPlatform.appId);
}
});
}
});
}
@ -199,63 +104,25 @@ export class MenuManagerComponentsIndexComponent implements OnInit {
this.sf.reset();
}
collapse(array: TreeNodeInterface[], data: TreeNodeInterface, $event: boolean): void {
if (!$event) {
if (data.children) {
data.children.forEach(d => {
const target = array.find(a => a.key === d.key)!;
target.expand = false;
this.collapse(array, target, false);
});
} else {
return;
menuImport(index: number) {
if (this.listOfMapData?.length > 0) {
this.service.msgSrv.warning('请先清空菜单');
return;
}
if (!this.selectedPlatform) {
return;
}
this.service.menuImport(this.selectedPlatform.enName, this.selectedPlatform.appId);
}
delMenu(type: number) {
this.modal.confirm({
nzTitle: '<i>删除确认</i>',
nzContent: `是否确认删除?`,
nzOnOk: () => {
this.service.getMenuByAppID(type === 0 ? 'A48F72F0A304427F921794BAD86B3522' : this.envSrv.env.appId);
}
}
}
convertTreeToList(root: TreeNodeInterface): TreeNodeInterface[] {
const stack: TreeNodeInterface[] = [];
const array: TreeNodeInterface[] = [];
const hashMap = {};
stack.push({ ...root, level: 0, expand: true });
while (stack.length !== 0) {
const node = stack.pop()!;
this.visitNode(node, hashMap, array);
if (node.children) {
for (let i = node.children.length - 1; i >= 0; i--) {
stack.push({ ...node.children[i], level: node.level! + 1, expand: false, parent: node, iconType: this.formatIcon(node.children[i].icon) });
}
}
}
return array;
}
visitNode(node: TreeNodeInterface, hashMap: { [key: string]: boolean }, array: TreeNodeInterface[]): void {
if (!hashMap[node.key]) {
hashMap[node.key] = true;
array.push(node);
}
}
private formatIcon(icon: any) {
let value = icon;
// compatible `anticon anticon-user`
if (~icon.indexOf(`anticon-`)) {
value = value.split('-').slice(1).join('-');
}
return value;
});
}
}
export interface TreeNodeInterface {
key: string;
name: string;
age?: number;
level?: number;
expand?: boolean;
address?: string;
children?: TreeNodeInterface[];
parent?: TreeNodeInterface;
[key: string]: any;
}

View File

@ -0,0 +1,9 @@
<div *ngIf="schema">
<sf #sf [compact]="true" [ui]="ui" [schema]="schema" [button]="'none'" [formData]="formData"> </sf>
</div>
<div class="modal-footer">
<button nz-button type="button" (click)="close()">{{ isDisabled ? '关闭' : '取消' }}</button>
<button nz-button type="button" nzType="primary" (click)="sure()" *ngIf="!isDisabled"
[disabled]="!sf?.valid">确定</button>
</div>

View File

@ -0,0 +1,148 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { SFComponent, SFSchema, SFUISchema } from '@delon/form';
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { SettingMenuComponent } from 'src/app/routes/sys-setting/components/role-management/menu/menu.component';
import { MenuManagerService } from '../../../services/menu-manager.service';
@Component({
selector: 'app-menu-modal',
templateUrl: './menu-modal.component.html',
styleUrls: ['./menu-modal.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MenuModalComponent implements OnInit {
@ViewChild('sf', { static: false })
sf!: SFComponent;
formData: any;
schema!: SFSchema;
ui!: SFUISchema;
isDisabled = false;
params = {};
constructor(public service: MenuManagerService, private modal: NzModalRef, private cdr: ChangeDetectorRef) {}
ngOnInit(): void {
if (this.formData.id) {
this.loadMenu();
} else {
this.initSF();
}
}
initSF(data?: any) {
this.schema = {
properties: {
text: {
title: '菜单名称',
type: 'string',
default: this.formData.text,
maxLength: 20,
ui: {
widget: this.isDisabled ? 'text' : 'string',
placeholder: '请输入菜单名称'
}
},
keyCode: {
title: '菜单编码',
type: 'string',
default: this.formData.keyCode,
ui: {
widget: this.isDisabled ? 'text' : 'string',
placeholder: '请输入菜单编码'
}
},
isLeaf: {
title: '是否叶子节点',
type: 'boolean',
default: this.formData.isLeaf || true,
enum: [true, false],
readOnly: this.isDisabled,
ui: {
widget: 'radio'
}
},
hide: {
title: '是否隐藏',
type: 'boolean',
default: this.formData.hide || false,
enum: [true, false],
readOnly: this.isDisabled,
ui: {
widget: 'radio'
}
},
link: {
title: '菜单路由',
type: 'string',
default: this.formData.link,
maxLength: 20,
ui: {
widget: this.isDisabled ? 'text' : 'string',
placeholder: '请输入菜单路由'
}
},
icon: {
title: '菜单图标',
type: 'string',
default: this.formData.icon,
ui: {
widget: this.isDisabled ? 'text' : 'string',
placeholder: '请输入菜单图标'
}
},
sortId: {
title: '排序',
type: 'number',
default: this.formData.sortId,
ui: {
widget: this.isDisabled ? 'text' : 'number'
}
}
},
required: ['text']
};
this.ui = {
'*': {
spanLabelFixed: 120,
grid: { span: 12 }
}
};
this.cdr.detectChanges();
}
loadMenu() {
this.service.request(this.service.$api_get_menu_by_id, { id: this.formData.id }).subscribe(res => {
if (res) {
this.formData = res;
this.initSF(this.formData);
}
});
}
close() {
this.modal.destroy();
}
sure() {
const params = {
...this.sf.value,
...this.params,
i18n: this.sf.value.keyCode,
menuType: 0,
reuse: 0,
shortcut: 0,
hideInBreadcrumb: 0,
functionType: 0,
sortId: this.sf.value.sortId?.toString() || null
};
console.log(params);
this.service.request(this.service.$api_add_one, params).subscribe(res => {
if (res) {
this.service.msgSrv.success(this.formData.id ? '修改菜单成功' : '新增菜单成功');
this.modal.destroy(true);
}
});
}
}