UNPKG

dbweb-common

Version:

用`yarn add dbweb-common`安装,不要忘记修改`angular.json`里的 `architect\build\options\assets`,加上

1,193 lines (1,184 loc) 1.03 MB
import { CommonModule, registerLocaleData, formatDate } from '@angular/common'; import { Component, Inject, HostBinding, ViewChild, NgModule, Injectable, ɵɵdefineInjectable, ɵɵinject, EventEmitter, Input, Output, Directive, ViewEncapsulation, ContentChildren, ViewChildren, LOCALE_ID, Injector, INJECTOR, Optional, ElementRef, NO_ERRORS_SCHEMA, ChangeDetectorRef, Renderer2, HostListener, CUSTOM_ELEMENTS_SCHEMA, Pipe } from '@angular/core'; import { clearText, clearCategory, RouteElementService, SimpleReuseStrategy, ElementsService, ProjectService, CurrentService, AuthloginService, ApiService, eleSwitchDept, CoreModule, BillControllerService, AuthService, StoreService, ApplicationInited, ElementApiService, BillFieldDataType, BillOperate, BillBackfaceService, IsDuplicatePKError, SaveStateData, CurrentApiService, fullApiPath, Element } from 'dbweb-core'; import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule, MatButtonModule, MatDialog, MatFormFieldModule as MatFormFieldModule$1, MatInputModule as MatInputModule$1, MatSnackBar, MatIconRegistry as MatIconRegistry$1, MatFormField, MatCheckbox, MatIconModule as MatIconModule$1, MatSnackBarModule, MatCheckboxModule, MatSelectModule, MatRadioModule, MatTableModule, MatSlideToggleModule, MatButtonToggleModule, MatDividerModule as MatDividerModule$1, MatTooltipModule, MatAutocompleteModule, MatSidenavModule as MatSidenavModule$1, MatChipsModule, MatMenuModule as MatMenuModule$1, MatExpansionModule as MatExpansionModule$1, MatProgressSpinnerModule, MatTreeNestedDataSource as MatTreeNestedDataSource$1, MatTreeModule as MatTreeModule$1 } from '@angular/material'; import { moveItemInArray, DragDropModule, CdkDropListGroup, CdkDropList } from '@angular/cdk/drag-drop'; import { FormControl, Validators, FormsModule, ReactiveFormsModule, FormGroup, NgControl, FormControlName } from '@angular/forms'; import { MatBadgeModule } from '@angular/material/badge'; import { MatButtonModule as MatButtonModule$1 } from '@angular/material/button'; import { MatRippleModule } from '@angular/material/core'; import { MatDialogRef as MatDialogRef$1, MatDialogModule as MatDialogModule$1, MatDialog as MatDialog$1 } from '@angular/material/dialog'; import { MatDividerModule } from '@angular/material/divider'; import { MatIconModule, MatIconRegistry } from '@angular/material/icon'; import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTab, MatTabsModule } from '@angular/material/tabs'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatTreeNestedDataSource, MatTreeModule } from '@angular/material/tree'; import { BrowserModule, Title, DomSanitizer } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NavigationEnd, Router, RouterLink, RouterModule, RoutesRecognized } from '@angular/router'; import { ClipboardModule, ClipboardService } from 'ngx-clipboard'; import { trigger, transition, style, query, group, animate, state } from '@angular/animations'; import { map, filter, tap, startWith, catchError, take, debounceTime } from 'rxjs/operators'; import { BehaviorSubject, Subscription, forkJoin, of, throwError, Subject, from } from 'rxjs'; import { NestedTreeControl } from '@angular/cdk/tree'; import { MatInputModule } from '@angular/material/input'; import { MatFormFieldModule } from '@angular/material/form-field'; import localeZh from '@angular/common/locales/zh-Hans'; import * as pinyin_ from 'pinyin'; import pinyin___default, { } from 'pinyin'; import { AceEditorModule } from 'ng2-ace-editor'; import { v1 } from 'uuid'; import ace from 'ace-builds'; import { HttpErrorResponse, HttpEventType, HttpClient } from '@angular/common/http'; import { ViewportRuler, OverlayContainer } from '@angular/cdk/overlay'; import { Ng5SliderModule } from 'ng5-slider'; import { MatCheckboxModule as MatCheckboxModule$1 } from '@angular/material/checkbox'; import { MatExpansionModule } from '@angular/material/expansion'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatSelectModule as MatSelectModule$1 } from '@angular/material/select'; import { MatStepperModule } from '@angular/material/stepper'; import { MatTableModule as MatTableModule$1 } from '@angular/material/table'; import { CalendarDateFormatter, CalendarView, CalendarModule, DateAdapter } from 'angular-calendar'; import { adapterFactory } from 'angular-calendar/date-adapters/date-fns'; import { MatCardModule } from '@angular/material/card'; import { MatChipsModule as MatChipsModule$1 } from '@angular/material/chips'; import { MatGridListModule } from '@angular/material/grid-list'; import { MatTooltipModule as MatTooltipModule$1 } from '@angular/material/tooltip'; import { SelectionModel } from '@angular/cdk/collections'; import { MatSortModule } from '@angular/material/sort'; import { MatRadioModule as MatRadioModule$1 } from '@angular/material/radio'; import { MatSnackBar as MatSnackBar$1, MatSnackBarModule as MatSnackBarModule$1 } from '@angular/material/snack-bar'; import { Md5 } from 'ts-md5'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class ConfirmDialogComponent { /** * @param {?} dialogRef * @param {?} data */ constructor(dialogRef, data) { this.dialogRef = dialogRef; this.data = data; this.hostClass = true; } /** * @return {?} */ onNoClick() { this.dialogRef.close(); } /** * @return {?} */ ngOnInit() { this.removeView.nativeElement.parentElement.parentElement.style = 'padding:0px'; } } ConfirmDialogComponent.decorators = [ { type: Component, args: [{ selector: 'common-confirm-dialog', template: "<div #removeView class=\"\u5220\u9664\">\r\n\t<div class=\"tit\">\r\n\t\t\t<b >{{ data }}</b>\r\n\t</div>\r\n\t<div class=\"\u529F\u80FD\u6309\u94AE\">\r\n\t\t<button class=\"false-icon\" mat-button [mat-dialog-close]=\"false\">\u53D6\u6D88</button>\r\n\t\t<button class=\"true-icon\" color=\"primary\" mat-button [mat-dialog-close]=\"true\">\u786E\u5B9A</button>\r\n\t</div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.\u5220\u9664{position:relative;display:flex;justify-content:space-between;flex-direction:column;width:100%;height:100%;box-sizing:border-box;padding:24px 24px 16px}.\u5220\u9664 b{font-size:20px}.tit{display:flex;align-items:center;box-sizing:border-box;width:100%;height:104px}.\u529F\u80FD\u6309\u94AE{width:100%;box-sizing:border-box;text-align:right}.\u529F\u80FD\u6309\u94AE .mat-button{width:64px;height:32px}.\u529F\u80FD\u6309\u94AE .true-icon{margin-left:8px}"] }] } ]; /** @nocollapse */ ConfirmDialogComponent.ctorParameters = () => [ { type: MatDialogRef }, { type: String, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] } ]; ConfirmDialogComponent.propDecorators = { hostClass: [{ type: HostBinding, args: ['class.confirm-dialog-theme',] }], removeView: [{ type: ViewChild, args: ['removeView', { static: true },] }] }; if (false) { /** @type {?} */ ConfirmDialogComponent.prototype.hostClass; /** @type {?} */ ConfirmDialogComponent.prototype.removeView; /** @type {?} */ ConfirmDialogComponent.prototype.dialogRef; /** @type {?} */ ConfirmDialogComponent.prototype.data; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class ConfirmDialogModule { } ConfirmDialogModule.decorators = [ { type: NgModule, args: [{ declarations: [ConfirmDialogComponent], imports: [CommonModule, MatDialogModule, MatButtonModule], exports: [ConfirmDialogComponent], entryComponents: [ConfirmDialogComponent] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const CTRL_RECORDVIEW = 'recordview'; /** @type {?} */ const CTRL_INDEX = 'index'; /** @type {?} */ const CTRL_EXPORT = 'export'; /** @type {?} */ const CTRL_LOGIN = 'login'; /** @type {?} */ const CTRL_ELEMENT = 'element'; /** @type {?} */ const CTRL_VERSION = 'version'; /** @type {?} */ const CTRL_TASK = 'task'; /** @type {?} */ const CTRL_IMPORT = 'import'; /** @type {?} */ const CTRL_USERINFO = 'userinfo'; /** @type {?} */ const CTRL_UPDATE = 'update'; /** @type {?} */ const CTRL_ROLE = 'role'; /** @type {?} */ const CTRL_USER = 'user'; /** @type {?} */ const CTRL_NOTICE = 'notice'; /** @type {?} */ const CTRL_REMOVESEL = 'removesel'; /** @type {?} */ const CTRL_DUMP_INSTITUTION = 'dumpInstitution'; /** @type {?} */ const portraitDefault = '/front/assets/userinfo/portrait_default.png'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} e * @return {?} */ function label(e) { if (e.Label) { return clearText(e.Label); } return clearText(e.Name); } class HomeTabfunctionService { /** * @param {?} eles */ constructor(eles) { this.eles = eles; } /** * @return {?} */ get category() { return this.eles.currentElementListen.pipe(map((/** * @param {?} v * @return {?} */ v => (v ? clearCategory(v.element.Category).replace('/', '>') + '>' + label(v.element) : null)))); } } HomeTabfunctionService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ HomeTabfunctionService.ctorParameters = () => [ { type: RouteElementService } ]; /** @nocollapse */ HomeTabfunctionService.ngInjectableDef = ɵɵdefineInjectable({ factory: function HomeTabfunctionService_Factory() { return new HomeTabfunctionService(ɵɵinject(RouteElementService)); }, token: HomeTabfunctionService, providedIn: "root" }); if (false) { /** @type {?} */ HomeTabfunctionService.prototype.eles; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class Tab { /** * @param {?} state */ constructor(state) { for (const key of Object.keys(state)) { this[key] = state[key]; } this.titleObservable = new BehaviorSubject(state.title); } /** * @return {?} */ data() { return { url: this.url, key: this.key, title: this.title }; } } if (false) { /** @type {?} */ Tab.prototype.url; /** @type {?} */ Tab.prototype.key; /** @type {?} */ Tab.prototype.title; /** @type {?} */ Tab.prototype.titleObservable; } class TabsService { /** * @param {?} router * @param {?} eles */ constructor(router, eles) { this.router = router; this.eles = eles; this.tabs = []; } // 激活一个tab,如果不存在,则新增并激活 /** * @param {?} data * @return {?} */ activeTab(data) { /** @type {?} */ const find = this.tabs.findIndex((/** * @param {?} v * @return {?} */ v => v.key === data.key)); if (find === -1) { this.tabs.push(new Tab(data)); this._activeIndex = this.tabs.length - 1; } else { this._activeIndex = find; // 同时需要更新url和title this.tabs[this._activeIndex].url = data.url; this.tabs[this._activeIndex].title = data.title; } } // 删除指定序号的tab,并切换激活的tab,如果只有一个tab,则不能被删除 // 返回true指示激活页已经切换 /** * @param {?} index * @return {?} */ removeTab(index) { if (this.tabs.length === 1) { return false; } /** @type {?} */ const deleteURL = this.tabs[index].url.toString(); // 如果是关闭当前页面,则会引起路由变化,所以需要在导航结束事件中删除,因为导航过程中还会进行保存 if (index === this._activeIndex) { /** @type {?} */ const sub = this.router.events.subscribe((/** * @param {?} v * @return {?} */ v => { if (v instanceof NavigationEnd) { SimpleReuseStrategy.deleteRouteSnapshot(deleteURL); sub.unsubscribe(); } })); } else { SimpleReuseStrategy.deleteRouteSnapshot(deleteURL); } this.tabs.splice(index, 1); if (this._activeIndex === index) { this._activeIndex = Math.min(this.tabs.length - 1, index); return true; } if (this._activeIndex > index) { this._activeIndex--; } return false; } // 删除所有的页,一般是logout /** * @return {?} */ clear() { this.tabs.splice(0); this._activeIndex = undefined; SimpleReuseStrategy.clearRouteSnapshot(); } // 关闭当前页,并自动导航到新的页 /** * @return {?} */ close() { if (this.activeIndex >= 0) { /** @type {?} */ const idx = this.activeIndex; if (this.tabs.length === 1) { this.router.navigateByUrl(this.eles.frontElementURL(this.eles.indexElementName)).then((/** * @return {?} */ () => { this.removeTab(idx); })); } if (this.removeTab(idx)) { this.router.navigateByUrl(this.active.url, { state: this.active.data() }); } } } /** * @return {?} */ get active() { if (this._activeIndex >= 0) { return this.tabs[this._activeIndex]; } return undefined; } /** * @return {?} */ get activeIndex() { return this._activeIndex; } /** * @param {?} val * @return {?} */ set activeIndex(val) { this._activeIndex = val; } } TabsService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ TabsService.ctorParameters = () => [ { type: Router }, { type: ElementsService } ]; /** @nocollapse */ TabsService.ngInjectableDef = ɵɵdefineInjectable({ factory: function TabsService_Factory() { return new TabsService(ɵɵinject(Router), ɵɵinject(ElementsService)); }, token: TabsService, providedIn: "root" }); if (false) { /** @type {?} */ TabsService.prototype.tabs; /** @type {?} */ TabsService.prototype._activeIndex; /** * @type {?} * @private */ TabsService.prototype.router; /** * @type {?} * @private */ TabsService.prototype.eles; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class HomeComponent { /** * @param {?} routerEle * @param {?} eles * @param {?} tabFun * @param {?} tabs */ constructor(routerEle, eles, tabFun, tabs) { this.routerEle = routerEle; this.eles = eles; this.tabFun = tabFun; this.tabs = tabs; this.hostClass = true; this.subs = []; this.copystate = false; this.subs.push(this.routerEle.currentElementListen .pipe(filter((/** * @param {?} ele * @return {?} */ ele => ele && ele.element && ele.element.Controller !== CTRL_LOGIN))) .subscribe((/** * @param {?} ele * @return {?} */ ele => { /** @type {?} */ let state = (/** @type {?} */ (ele.state)); if (!state) { /** @type {?} */ let key = ele.url; /** @type {?} */ const arr = key.split('/'); // 功能类的,需要去除子路由作为key,防止出现多余的tab if (!ele.element.Bill && arr.length > 5) { key = arr.slice(0, 5).join('/'); // 需要处理query /** @type {?} */ const queryArr = arr[arr.length - 1].split('?'); if (queryArr.length > 1) { key += '?' + queryArr[1]; } } state = { url: ele.urlObj, key: key, title: ele.element.title() }; } this.tabs.activeTab(state); }))); this.category = this.tabFun.category; } /** * @return {?} */ ngOnInit() { } /** * @return {?} */ ngOnDestroy() { this.subs.forEach((/** * @param {?} v * @return {?} */ v => v.unsubscribe())); } } HomeComponent.decorators = [ { type: Component, args: [{ selector: 'common-home', template: "<div class=\"home-container-nav\">\r\n\t<common-home-nav></common-home-nav>\r\n</div>\r\n<div class=\"home-container-content\">\r\n\t<div class=\"tab-all\">\r\n\t\t<app-router-tab #tabNav class=\"tabNav\">\r\n\t\t\t<app-router-tab-item\r\n\t\t\t\t*ngFor=\"let tab of tabs.tabs; let index = index\"\r\n\t\t\t\t[routerLink]=\"tab.url\" class=\"tabA\"\r\n\t\t\t\tlabel=\"{{ tab.titleObservable | async }}\">\r\n\t\t\t</app-router-tab-item>\r\n\t\t</app-router-tab>\r\n\t\t<div class=\"tab-nav-right\">\r\n\t\t\t<button mat-icon-button ngxClipboard [cbContent]=\"category | async\"\r\n\t\t\t\t(mousemove)=\"copystate = true\" (mouseout)=\"copystate = false\">\r\n\t\t\t\t<mat-icon class=\"\u590D\u5236\u56FE\u6807\" [class.\u590D\u5236\u60AC\u6D6E]=\"copystate\"\r\n\t\t\t\t\taria-label=\"\u590D\u5236\u7C7B\u522B\" svgIcon=\"content_copy\"></mat-icon>\r\n\t\t\t</button>\r\n\t\t\t<button mat-stroked-button class=\"\u8BED\u8A00\">Eng</button>\r\n\t\t</div>\r\n\t\t<div class=\"\u590D\u5236\u8DEF\u5F84\" [class.\u590D\u5236\u60AC\u6D6E\u72B6\u6001]=\"!copystate\">\r\n\t\t\t<span class=\"\u7C7B\u522B\">{{ category | async }}</span>\r\n\t\t</div>\r\n\t</div>\r\n\r\n\t<div class=\"content-home\" [@routerTransition]=\"tabs.activeIndex\">\r\n\t\t<core-router-outlet #outlet=\"coreRouterOutlet\"></core-router-outlet>\r\n\t</div>\r\n</div>", animations: [ trigger('routerTransition', [ transition(':enter, * => -1', []), transition(':increment', [ style({ position: 'relative', overflow: 'hidden' }), query(':enter, :leave', style({ position: 'absolute', width: '100%', height: '100%' }), { optional: true }), group([ query(':enter', [ style({ transform: 'translateX(-100%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' })) ], { optional: true }), query(':leave', [ style({ transform: 'translateX(0%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' })) ], { optional: true }) ]) ]), transition(':decrement', [ style({ position: 'relative', overflow: 'hidden' }), query(':enter, :leave', style({ position: 'absolute', width: '100%', height: '100%' }), { optional: true }), group([ query(':enter', [ style({ transform: 'translateX(100%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' })) ], { optional: true }), query(':leave', [ style({ transform: 'translateX(0%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(-100%)' })) ], { optional: true }) ]) ]) ]) ], styles: ["@charset \"UTF-8\";:host{width:100%;height:100%;padding:0;margin:0;display:flex;align-items:stretch}.home-container-nav{flex-shrink:0;z-index:10}.home-container-content{height:100%;display:flex;flex-direction:column;width:10%;flex-grow:1;flex-shrink:1}.home-container-content .tab-all{display:flex;height:30px}.home-container-content .tab-all .tabNav{width:10%;flex-grow:1;flex-shrink:1}.home-container-content .tab-all .tab-nav-right{height:30px;line-height:30px;font-size:12px;position:relative;display:block}.home-container-content .tab-all .tab-nav-right button{width:24px;height:24px;line-height:24px}.home-container-content .tab-all .tab-nav-right button .\u590D\u5236\u56FE\u6807{width:16px;height:16px;margin-bottom:6px}.home-container-content .tab-all .tab-nav-right .\u8BED\u8A00{font-size:12px;height:24px;width:64px;margin:0 8px;padding:0;line-height:20px;text-align:center}.home-container-content .\u590D\u5236\u8DEF\u5F84{height:32px;position:absolute;right:0;top:30px;font-size:12px;color:#fff;line-height:32px;border-radius:4px;padding:0 8px;z-index:9;text-align:center;background-color:rgba(0,0,0,.6);box-shadow:0 4px 8px 0 rgba(0,0,0,.14)}.home-container-content .\u590D\u5236\u60AC\u6D6E\u72B6\u6001{display:none}.home-container-content .content-home{width:100%;height:10%;box-sizing:border-box;flex-grow:1;flex-shrink:1}"] }] } ]; /** @nocollapse */ HomeComponent.ctorParameters = () => [ { type: RouteElementService }, { type: RouteElementService }, { type: HomeTabfunctionService }, { type: TabsService } ]; HomeComponent.propDecorators = { hostClass: [{ type: HostBinding, args: ['class.c-home',] }], tabNavs: [{ type: ViewChild, args: ['tabNav', { static: true },] }] }; if (false) { /** @type {?} */ HomeComponent.prototype.hostClass; /** @type {?} */ HomeComponent.prototype.subs; /** @type {?} */ HomeComponent.prototype.tabNavs; /** @type {?} */ HomeComponent.prototype.category; /** @type {?} */ HomeComponent.prototype.copystate; /** * @type {?} * @private */ HomeComponent.prototype.routerEle; /** @type {?} */ HomeComponent.prototype.eles; /** * @type {?} * @private */ HomeComponent.prototype.tabFun; /** @type {?} */ HomeComponent.prototype.tabs; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} val * @return {?} */ function convertBoolean(val) { return val === 'true'; } class MainNavService { constructor() { this._navMin = new BehaviorSubject(convertBoolean(localStorage.getItem('main-nav-min'))); this.navMin = this._navMin.pipe(tap((/** * @param {?} v * @return {?} */ v => { localStorage.setItem('main-nav-min', v ? 'true' : 'false'); }))); } /** * @param {?} val * @return {?} */ setNavMin(val) { this._navMin.next(val); } /** * @return {?} */ getCurrent() { return this._navMin.getValue(); } } MainNavService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ MainNavService.ngInjectableDef = ɵɵdefineInjectable({ factory: function MainNavService_Factory() { return new MainNavService(); }, token: MainNavService, providedIn: "root" }); if (false) { /** * @type {?} * @private */ MainNavService.prototype._navMin; /** @type {?} */ MainNavService.prototype.navMin; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NavtreeService { // 图标 // get data(): NavItem[] { // console.log(this.dataChange.value); // return this.dataChange.value; // } /** * @param {?} eles * @param {?} project */ constructor(eles, project) { this.eles = eles; this.project = project; this.root = { children: [] }; // dataChange = new BehaviorSubject<NavItem[]>([]); this.icons = ['security', 'dns', 'gamepad']; // 图标 // this.initialize(); this.init(); for (let i = 0; i < Math.min(this.root.children.length, this.icons.length); i++) { this.root.children[i].iconName = this.icons[i]; } } /** * @return {?} */ init() { // 设置项目图标 if (this.project.categoryIcons && this.project.categoryIcons.length > 0) { this.icons = this.project.categoryIcons; } // 如果已经初始化过,则跳出 if (this.root.children.length > 0) { return; } this.eles.getElesAsArray().forEach((/** * @param {?} element * @return {?} */ element => { // 后端api或者子级工作元素的,不需要加入到node列表中 if (!element.NotMenu) { this.addElement(element, this.root, element.Category.split('/'), 0, null, element.Icon); } })); // console.log(this.root.children[0].iconName); // console.log(this.root); } /** * @private * @param {?} str * @return {?} */ clearText(str) { if (str.search(/[0-9]{2}\./) > -1) { return str.substr(3); } return str; } // 采用插入排序方法逐条插入 /** * @private * @param {?} ele * @param {?} parent * @param {?} paths * @param {?} level * @param {?} parents * @param {?} iconName * @return {?} */ addElement(ele, parent, paths, level, parents, iconName) { if (paths.length === 0) { // 实际插入的菜单项,也需要排序 /** @type {?} */ const idx = parent.children.findIndex((/** * @param {?} item * @return {?} */ item => (ele.Label || ele.Name).localeCompare(item.fullTitle || item.name) <= 0)); /** @type {?} */ const node = { name: ele.Name, fullTitle: ele.Label, title: this.clearText(ele.Label || ele.Name), url: this.eles.frontElementURL(ele.Name, decodeURI(ele.URL)), level: level, parent: parents, iconName: iconName }; if (idx === -1) { parent.children.push(node); } else { parent.children.splice(idx, 0, node); } return; } /** @type {?} */ const findIdx = parent.children.findIndex((/** * @param {?} item * @return {?} */ item => paths[0].localeCompare(item.name) <= 0)); /** @type {?} */ let categoryNode; if (findIdx !== -1 && parent.children[findIdx].name === paths[0]) { categoryNode = parent.children[findIdx]; } else { categoryNode = { name: paths[0], fullTitle: paths[0], title: this.clearText(paths[0]), level: level, parent: parents, iconName: iconName, children: [] }; // 如果找不到,则说明比里面任何一个都大,则是追加到最后一个 if (findIdx === -1) { parent.children.push(categoryNode); } else { parent.children.splice(findIdx, 0, categoryNode); } } this.addElement(ele, categoryNode, paths.slice(1), level + 1, categoryNode, iconName); } } NavtreeService.decorators = [ { type: Injectable } ]; /** @nocollapse */ NavtreeService.ctorParameters = () => [ { type: ElementsService }, { type: ProjectService } ]; if (false) { /** @type {?} */ NavtreeService.prototype.root; /** @type {?} */ NavtreeService.prototype.icons; /** * @type {?} * @private */ NavtreeService.prototype.eles; /** * @type {?} * @private */ NavtreeService.prototype.project; } class NavHome { /** * @param {?} current * @param {?} database * @param {?} prj */ constructor(current, database, prj) { this.current = current; this.database = database; this.prj = prj; this.chatMessages = []; this.unread = null; // 未读信息数 // 未读信息数 this.openNodeCurrent = []; this.activeNode = []; this.subs = []; } /** * @param {?} node * @return {?} */ recursionFun(node) { if (node.level <= 0) { return this.openNodeCurrent.push(node); } if (node.level >= 1) { this.openNodeCurrent.push(node); this.recursionFun(node.parent); } } /** * @param {?} node * @return {?} */ recursionFuns(node) { if (node.level <= 0) { return this.activeNode.push(node); } if (node.level >= 1) { this.activeNode.push(node); this.recursionFuns(node.parent); } } /** * @param {?} node * @return {?} */ gradually(node) { if (this.activeNode.length !== 0) { this.activeNode.splice(0, this.activeNode.length); } this.recursionFuns(node); } /** * @param {?} node * @return {?} */ openNode(node) { /** @type {?} */ const openboolean = this.openNodeCurrent.includes(node); if (this.openNodeCurrent.length !== 0) { this.openNodeCurrent.splice(0, this.openNodeCurrent.length); } if (openboolean) { if (node.level >= 1) { this.recursionFun(node.parent); } if (node.level === 0) { this.recursionFun(this.database.root); } } else { this.recursionFun(node); } } /** * @return {?} */ messages() { /** @type {?} */ const chatData = JSON.parse(this.prj.loadData('chatdata')); if (chatData == null) { this.prj.saveData('chatdata', JSON.stringify(this.chatMessages)); } this.subs.push(this.current.wsChat.observable.subscribe((/** * @param {?} n * @return {?} */ n => { this.chatMessages.push(n); this.prj.saveData('chatdata', JSON.stringify(this.chatMessages)); if (n != null) { this.unread = this.unread + 1; } // console.log(JSON.parse(localStorage.getItem('chatdata'))); }), (/** * @param {?} err * @return {?} */ err => console.log(err)), (/** * @return {?} */ () => console.log('component')))); this.chatMessages = chatData; } /** * @param {?} item * @return {?} */ fromChildFunc(item) { if (this.activeNode.length !== 0) { this.activeNode.splice(0, this.activeNode.length); } this.recursionFuns(item); if (this.openNodeCurrent.length !== 0) { this.openNodeCurrent.splice(0, this.openNodeCurrent.length); } this.recursionFun(item); } } NavHome.decorators = [ { type: Injectable } ]; /** @nocollapse */ NavHome.ctorParameters = () => [ { type: CurrentService }, { type: NavtreeService }, { type: ProjectService } ]; if (false) { /** @type {?} */ NavHome.prototype.portraitURL; /** @type {?} */ NavHome.prototype.chatMessages; /** @type {?} */ NavHome.prototype.messageBody; /** @type {?} */ NavHome.prototype.unread; /** @type {?} */ NavHome.prototype.openNodeCurrent; /** @type {?} */ NavHome.prototype.activeNode; /** @type {?} */ NavHome.prototype.subs; /** * @type {?} * @private */ NavHome.prototype.current; /** * @type {?} * @private */ NavHome.prototype.database; /** * @type {?} * @private */ NavHome.prototype.prj; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class FileFlatNode { /** * @param {?} expandable * @param {?} filename * @param {?} level * @param {?} type */ constructor(expandable, filename, level, type) { this.expandable = expandable; this.filename = filename; this.level = level; this.type = type; } } if (false) { /** @type {?} */ FileFlatNode.prototype.expandable; /** @type {?} */ FileFlatNode.prototype.filename; /** @type {?} */ FileFlatNode.prototype.level; /** @type {?} */ FileFlatNode.prototype.type; } class HomeNavComponent { /** * @param {?} nav * @param {?} current * @param {?} eles * @param {?} database * @param {?} auth * @param {?} routeEle * @param {?} prj * @param {?} navMain * @param {?} router * @param {?} tabs */ constructor(nav, current, eles, database, auth, routeEle, prj, navMain, router, tabs) { this.nav = nav; this.current = current; this.eles = eles; this.database = database; this.auth = auth; this.routeEle = routeEle; this.prj = prj; this.navMain = navMain; this.router = router; this.tabs = tabs; // 是正常导航还是简略导航 this.isMinNav = true; // 是否打开对话框 this.isOpenDialog = false; this.navItems = []; this._getChildren = (/** * @param {?} node * @return {?} */ (node) => node.children); this.isMinNav = this.navMain.getCurrent(); this.navMain.navMin.subscribe((/** * @param {?} v * @return {?} */ v => { this.switchNavToMin(v); })); this.current.change$.subscribe((/** * @param {?} v * @return {?} */ v => { if (v && v.HeadPortrait) { this.nav.portraitURL = v.portraitURL; } else { this.nav.portraitURL = portraitDefault; } })); } /** * @param {?} v * @return {?} */ switchNavToMin(v) { if (v === this.isMinNav) { return; } setTimeout((/** * @return {?} */ () => { this.isMinNav = v; }), 300); if (v) { this.maxNavContainer.nativeElement.style.width = '80px'; this.maxNavContainer.nativeElement.style.transition = 'all 0.3s'; } else { this.minNavContainer.nativeElement.style.width = '240px'; this.minNavContainer.nativeElement.style.transition = 'all 0.3s'; } } /** * @return {?} */ ngOnInit() { this.nestedTreeControl = new NestedTreeControl(this._getChildren); this.nestedDataSource = new MatTreeNestedDataSource(); this.nestedDataSource.data = this.database.root.children; // this.buttonHight(); this.navItems = this.nestedDataSource.data; this.nav.subs.push(this.routeEle.currentElementListen.subscribe((/** * @param {?} e * @return {?} */ e => { // 偶尔会出现e未null的情况,原因未探查,等有时间再改造 if (e && e.element) { this.currentNode = null; this.obtainNode(e.element.Name, this.navItems); if (this.nav.activeNode.length !== 0 && this.currentNode !== null) { this.nav.activeNode.splice(0, this.nav.activeNode.length); } if (this.nav.openNodeCurrent.length !== 0 && this.currentNode !== null) { this.nav.openNodeCurrent.splice(0, this.nav.openNodeCurrent.length); } if (this.currentNode !== null) { this.nav.recursionFuns(this.currentNode); this.nav.recursionFun(this.currentNode); } } }))); this.nav.messages(); } /** * @return {?} */ ngOnDestroy() { this.nav.subs.forEach((/** * @param {?} v * @return {?} */ v => v.unsubscribe())); } /** * @return {?} */ logout() { this.router .navigateByUrl('/login' + '/' + this.prj.apiNav()[0] + '/' + this.prj.apiNav()[1] + '/login') .then((/** * @return {?} */ () => { // 必须要在路由切换之后,因为只有切换后,才会在reuse中存在,才能clear this.tabs.clear(); // 一定要先清除所有的tab页面,用于取消订阅curr的变化 this.auth.logoutDefault().subscribe(); })); } /** * @param {?} _ * @param {?} nodeData * @return {?} */ hasNestedChild(_, nodeData) { return !!nodeData.children && nodeData.children.length > 0; } // 对话框显示 /** * @return {?} */ openDialog() { this.isOpenDialog = true; // this.unread = null; setTimeout((/** * @return {?} */ () => { this.dialogScrolls(); }), 0); } /** * @return {?} */ closeDialog() { this.isOpenDialog = false; } // 获取当前节点的node /** * @param {?} title * @param {?} navItems * @return {?} */ obtainNode(title, navItems) { for (let i = 0; i <= navItems.length - 1; i++) { if (navItems[i].name === title) { this.currentNode = navItems[i]; } if (navItems[i].children !== undefined && this.currentNode == null) { this.obtainNode(title, navItems[i].children); } } } /** * @return {?} */ sendMessage() { if (this.nav.messageBody) { this.current.wsChat.next({ Creator: this.prj.Creator(), Project: this.prj.Name(), From: this.current.data.UserName, Addr: '', Time: null, Data: this.nav.messageBody }); this.nav.messageBody = ''; } setTimeout((/** * @return {?} */ () => { this.dialogScrolls(); }), 0); } // 输入框的回车事件 /** * @param {?} e * @return {?} */ keyDown(e) { /** @type {?} */ const ev = window.event || e; // 13是键盘上面固定的回车键 if (ev.keyCode === 13) { // 你要执行的方法 this.sendMessage(); } } // 将聊天窗口滚动条滚至最下方 /** * @return {?} */ dialogScrolls() { if (this.dialogScroll == null) { return; } this.nav.unread = null; this.dialogScroll.nativeElement.scrollTop = this.dialogScroll.nativeElement.scrollHeight; } // 判断是否已阅读最新消息 /** * @return {?} */ isNews() { /** @type {?} */ const isScrolledToBottom = this.dialogScroll.nativeElement.scrollHeight - this.dialogScroll.nativeElement.clientHeight <= this.dialogScroll.nativeElement.scrollTop + 1; if (isScrolledToBottom) { this.nav.unread = null; } } } HomeNavComponent.decorators = [ { type: Component, args: [{ selector: 'common-home-nav', template: "<div *ngIf=\"!isMinNav\" #maxNavContainer class=\"max-nav-container nav-container\">\r\n\t<div class=\"nav-top\">\r\n\t\t<div class=\"nav-title\">\r\n\t\t\t<div class=\"nav-title-logo\"><img [src]=\"prj.logoImageURL()\" /></div>\r\n\t\t\t<div class=\"nav-title-name\">\r\n\t\t\t\t<p\r\n\t\t\t\t\t[ngClass]=\"{'projectLabelMin': prj.projectLabelForShort.length>6}\">\r\n\t\t\t\t\t{{ prj.projectLabelForShort }}</p>\r\n\t\t\t\t<common-nav-selection-dept [isMinNav]=\"isMinNav\">\r\n\t\t\t\t</common-nav-selection-dept>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t\t<div (click)=\"switchNavToMin(!isMinNav)\" class=\"nav-switch\">\r\n\t\t\t<mat-icon svgIcon=\"chevron_left\"></mat-icon>\r\n\t\t</div>\r\n\t</div>\r\n\t<mat-divider class=\"nav-divider\"></mat-divider>\r\n\t<div class=\"\u5BFC\u822A\u6811\">\r\n\t\t<div class=\"slider slider-color\"></div>\r\n\t\t<mat-tree [dataSource]=\"nestedDataSource\" [treeControl]=\"nestedTreeControl\" class=\"example-tree\">\r\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node; index as i\" matTreeNodeToggle>\r\n\t\t\t\t<li (click)=\"nav.gradually(node)\" class=\"mat-tree-node\">\r\n\t\t\t\t\t<button [class.collapsed]=\"nav.activeNode.includes(node)\" [routerLink]=\"[node.url]\" mat-button\r\n\t\t\t\t\t\tclass=\"\u5BFC\u822A\u6309\u94AE\u60AC\u6D6E\u8272\">\r\n\t\t\t\t\t\t<mat-icon *ngIf=\"node.iconName\" class=\"menu-icon\" [svgIcon]=\"node.iconName\"></mat-icon>\r\n\t\t\t\t\t\t{{ node.title }}\r\n\t\t\t\t\t</button>\r\n\t\t\t\t</li>\r\n\t\t\t</mat-tree-node>\r\n\t\t\t<mat-nested-tree-node *matTreeNodeDef=\"let node; when: hasNestedChild; let i = index\" matTreeNodePadding>\r\n\t\t\t\t<div class=\"max-menu\" [class.\u5206\u652F\u80CC\u666F]=\"nav.openNodeCurrent.includes(node)\">\r\n\t\t\t\t\t<div *ngIf=\"node.level == 0\" [ngClass]=\"{\r\n\t\t\t\t\t\t\t'slider-color': nav.activeNode.includes(node),\r\n\t\t\t\t\t\t\t'max-left-slider': nav.activeNode.includes(node)\r\n\t\t\t\t\t\t}\"></div>\r\n\t\t\t\t\t<div class=\"mat-tree-node\">\r\n\t\t\t\t\t\t<button [class.collapsed]=\"nav.activeNode.includes(node)\" mat-button matTreeNodeToggle\r\n\t\t\t\t\t\t\t[attr.aria-label]=\"'toggle ' + node.title\" (click)=\"nav.openNode(node)\" class=\"\u5BFC\u822A\u6309\u94AE\u60AC\u6D6E\u8272\">\r\n\t\t\t\t\t\t\t<mat-icon *ngIf=\"node.level == 0\" svgIcon=\"{{ node.iconName }}\">\r\n\t\t\t\t\t\t\t</mat-icon>\r\n\t\t\t\t\t\t\t{{ node.title }}\r\n\t\t\t\t\t\t\t<mat-icon *ngIf=\"node.level != 0\" class=\"mat-icon-rtl-mirror\" svgIcon=\"{{\r\n\t\t\t\t\t\t\t\t\tnav.openNodeCurrent.includes(node)\r\n\t\t\t\t\t\t\t\t\t\t? 'expand_more'\r\n\t\t\t\t\t\t\t\t\t\t: 'chevron_right'\r\n\t\t\t\t\t\t\t\t}}\">\r\n\t\t\t\t\t\t\t</mat-icon>\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<ul [class.example-tree-invisible]=\"\r\n\t\t\t\t\t\t\t!nav.openNodeCurrent.includes(node)\r\n\t\t\t\t\t\t\">\r\n\t\t\t\t\t\t<ng-container matTreeNodeOutlet></ng-container>\r\n\t\t\t\t\t</ul>\r\n\t\t\t\t</div>\r\n\t\t\t</mat-nested-tree-node>\r\n\t\t</mat-tree>\r\n\t</div>\r\n\t<div class=\"nav-bottom\">\r\n\t\t<mat-divider class=\"nav-divider\"></mat-divider>\r\n\t\t<a class=\"nav-bottom-photo\" [routerLink]=\"eles.frontElementURL('userinfo')\">\r\n\t\t\t<div><img [src]=\"nav.portraitURL\" /></div>\r\n\t\t\t<p class=\"\u6635\u79F0\">{{ current.data.NickName || current.data.UserName}}</p>\r\n\t\t</a>\r\n\t\t<div class=\"nav-bottom-icon\">\r\n\t\t\t<div (click)=\"openDialog()\">\r\n\t\t\t\t<mat-icon matBadge=\"{{ nav.unread }}\" matBadgeColor=\"warn\" matBadgeSize=\"medium\" svgIcon=\"mail\">\r\n\t\t\t\t</mat-icon>\r\n\t\t\t\t<p>\u6D88\u606F</p>\r\n\t\t\t</div>\r\n\t\t\t<div (click)=\"logout()\">\r\n\t\t\t\t<mat-icon svgIcon=\"forward\"></mat-icon>\r\n\t\t\t\t<p>\u9000\u51FA</p>\r\n\t\t\t</div>\r\n\t\t\t<div>\r\n\t\t\t\t<mat-icon svgIcon=\"help\"></mat-icon>\r\n\t\t\t\t<p>\u5E2E\u52A9</p>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n\t<div *ngIf=\"isOpenDialog\" class=\"\u5BF9\u8BDD\u6846\">\r\n\t\t<div class=\"\u5BF9\u8BDD\u6846\u4E0A\u90E8\">\r\n\t\t\t<mat-icon (click)=\"closeDialog()\" svgIcon=\"expand_more\"></mat-icon>\r\n\t\t</div>\r\n\t\t<div #dialogScroll class=\"\u5BF9\u8BDD\u6846\u5185\u5BB9\">\r\n\t\t\t<p class=\"\u663E\u793A\u5BF9\u8BDD\" *ngFor=\"let message of nav.chatMessages\">\r\n\t\t\t\t[<span class=\"\u540D\u5B57\">{{ message.From }}</span>]\r\n\t\t\t\t<span class=\"\u65F6\u95F4\">{{\r\n\t\t\t\t\tmessage.Time | date: \"yyyy-MM-dd HH:mm:ss\"\r\n\t\t\t\t}}</span>\r\n\t\t\t\t<span class=\"\u5185\u5BB9\">{{ message.Data }}</span>\r\n\t\t\t</p>\r\n\t\t</div>\r\n\t\t<div class=\"\u5BF9\u8BDD\u6846\u5E95\u90E8\">\r\n\t\t\t<input mat-input class=\"\u8F93\u5165\u6846\" [(ngModel)]=\"nav.messageBody\" (keydown)=\"keyDown($event)\"\r\n\t\t\t\tplaceholder=\"\u8F93\u5165\u5185\u5BB9,\u56DE\u8F66\u53D1\u9001\" />\r\n\t\t\t<mat-icon (click)=\"sendMessage()\" svgIcon=\"send\"></mat-icon>\r\n\t\t</div>\r\n\t</div>\r\n</div>\r\n<div *ngIf=\"isMinNav\" #minNavContainer class=\"min-nav-container nav-container\">\r\n\t<div class=\"min-logo\"><img [src]=\"prj.logoImageURL()\" /></div>\r\n\t<div>\r\n\t\t<common-nav-selection-dept [isMinNav]=\"isMinNav\">\r\n\t\t</common-nav-selection-dept>\r\n\t\t<mat-divider class=\"nav-divider\"></mat-divider>\r\n\t</div>\r\n\t<div class=\"\u5BFC\u822A\u6811\u5C0F\">\r\n\t\t<div class=\"min-slider slider-color\"></div>\r\n\t\t<div class=\"\u83DC\u5355\u9879\" *ngFor=\"let item of navItems; index as i\" [class.\u5F53\u524D\u83DC\u5355\u9879]=\"nav.activeNode.includes(item)\">\r\n\t\t\t<div [ngClass]=\"{\r\n\t\t\t\t\t'slider-color': nav.activeNode.includes(item),\r\n\t\t\t\t\t'left-slider': nav.activeNode.includes(item)\r\n\t\t\t\t}\"></div>\r\n\t\t\t<!-- Handle branch node buttons here -->\r\n\t\t\t<div *ngIf=\"item.children && item.children.length > 0\">\r\n\t\t\t\t<button mat-button class=\"\u5BFC\u822A\u6309\u94AE\u60AC\u6D6E\u8272\" [class.collapsed]=\"nav.activeNode.includes(item)\"\r\n\t\t\t\t\t[matMenuTriggerFor]=\"menu.childMenu\">\r\n\t\t\t\t\t<mat-icon svgIcon=\"{{ item.iconName }}\"></mat-icon>\r\n\t\t\t\t\t{{ item.title }}\r\n\t\t\t\t</button>\r\n\t\t\t\t<common-menu [class.treebranch]=\"true\" #menu [items]=\"item.children\" [activeNode]=\"nav.activeNode\"\r\n\t\t\t\t\t(fromChild)=\"nav.fromChildFunc($event)\"></common-menu>\r\n\t\t\t</div>\r\n\t\t\t<!-- Leaf node buttons here -->\r\n\t\t\t<div *ngIf=\"!item.children || item.children.length === 0\">\r\n\t\t\t\t<button mat-button class=\"\u5BFC\u822A\u6309\u94AE\u60AC\u6D6E\u8272\">\r\n\t\t\t\t\t<mat-icon svgIcon=\"{{ item.iconName }}\"></mat-icon>\r\n\t\t\t\t\t{{ item.title }}\r\n\t\t\t\t</button>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n\t<div class=\"\u5BFC\u822A\u5E95\u90E8\u5C0F\">\r\n\t\t<mat-divider class=\"nav-divider\"></mat-divider>\r\n\t\t<button (click)=\"switchNavToMin(!isMinNav)\" mat-button>\r\n\t\t\t<mat-icon svgIcon=\"chevron_right\"></mat-icon>\u5C55\u5F00\r\n\t\t</button>\r\n\t\t<a class=\"nav-bottom-photo\" [routerLink]=\"eles.frontElementURL('userinfo')\">\r\n\t\t\t<div class=\"nav-bottom-photo-img\"><img [src]=\"nav.portraitURL\" /></div>\r\n\t\t\t<p class=\"\u6635\u79F0\">{{ current.data.NickName||current.data.UserName }}</p>\r\n\t\t</a>\r\n\t</div>\r\n</div>", providers: [NavtreeService, NavHome], styles: ["@charset \"UTF-8\";.max-nav-container{width:240px;height:100%;margin:0;padding:0;display:flex;flex-direction:column}.nav-top{width:100%;height:72px;display:flex;align-items:center;position:relative}.nav-top .nav-title{width:216px;height:48px;padding:0 8px 0 16px;display:flex}.nav-top .nav-title-logo{width:48px;height:48px}.nav-top .nav-title-logo img{width:100%;height:100%}.nav-top .nav-title-name{flex-grow:1;vertical-align:top;margin-left:8px;letter-spacing:1px}.nav-top .nav-title-name p{font-size:18px;width:100%;font-weight:700;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nav-top .nav-title-name .projectLabelMin{font-size:14px}.nav-top .nav-switch{width:32px;height:32px;border-radius:16px 0 0 16px;background-color:rgba(255,255,255,.2);position:absolute;right:0;bottom:4px}.nav-top .nav-switch .mat-icon{margin:4px;cursor:pointer}.nav-divider{z-index:2}.nav-menu-item{font-size:14px;height:32px;line-height:32px}.nav-bottom{margin:0;width:100%;height:98px}.nav-bottom .nav-bottom-photo{margin:16px 8px 0 12px}.nav-bottom .nav-bottom-icon{float:right;width:116