mirror of
https://gitee.com/eolink_admin/postcat.git
synced 2024-12-02 03:38:03 +08:00
feat: support preview text response & download
This commit is contained in:
parent
122fd25dc7
commit
cc0fac7e6f
@ -20,7 +20,7 @@
|
||||
"dependencies": {
|
||||
"@angular-cli/base-href-webpack": "1.0.16",
|
||||
"@angular/animations": "14.0.3",
|
||||
"@angular/cdk": "13.3.9",
|
||||
"@angular/cdk": "14.0.3",
|
||||
"@angular/common": "14.0.3",
|
||||
"@angular/compiler": "14.0.3",
|
||||
"@angular/core": "14.0.3",
|
||||
@ -37,6 +37,7 @@
|
||||
"angular": "1.8.2",
|
||||
"brace": "0.11.1",
|
||||
"js-beautify": "1.14.4",
|
||||
"lodash-es": "4.17.21",
|
||||
"markdown-it": "13.0.1",
|
||||
"monaco-editor": "0.33.0",
|
||||
"ng-zorro-antd": "13.3.2",
|
||||
@ -62,6 +63,7 @@
|
||||
"@ngx-translate/http-loader": "7.0.0",
|
||||
"@types/jasmine": "4.0.3",
|
||||
"@types/jasminewd2": "2.0.10",
|
||||
"@types/lodash-es": "4.17.6",
|
||||
"@types/markdown-it": "12.2.3",
|
||||
"@types/node": "18.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.29.0",
|
||||
|
@ -9,33 +9,15 @@
|
||||
<nz-select class="!w-[106px] flex-none" [(ngModel)]="model.request.method" formControlName="method">
|
||||
<nz-option *ngFor="let item of REQUEST_METHOD" [nzLabel]="item.key" [nzValue]="item.value"></nz-option>
|
||||
</nz-select>
|
||||
<div
|
||||
*ngIf="env.hostUri"
|
||||
nz-typography
|
||||
nzEllipsis
|
||||
class="env_front_uri"
|
||||
nzTooltipTitle="{{ env.hostUri }}"
|
||||
nzTooltipPlacement="bottom"
|
||||
nz-tooltip
|
||||
>
|
||||
<div *ngIf="env.hostUri" nz-typography nzEllipsis class="env_front_uri" nzTooltipTitle="{{ env.hostUri }}"
|
||||
nzTooltipPlacement="bottom" nz-tooltip>
|
||||
{{ env.hostUri }}
|
||||
</div>
|
||||
<nz-form-item nz-col class="fg1">
|
||||
<nz-form-control
|
||||
[nzValidateStatus]="this.validateForm.controls.uri"
|
||||
i18n-nzErrorTip
|
||||
nzErrorTip="Please enter URL"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
i18n-placeholder
|
||||
placeholder="Enter URL"
|
||||
name="uri"
|
||||
nz-input
|
||||
formControlName="uri"
|
||||
[(ngModel)]="model.request.uri"
|
||||
(change)="changeUri()"
|
||||
/>
|
||||
<nz-form-control [nzValidateStatus]="this.validateForm.controls.uri" i18n-nzErrorTip
|
||||
nzErrorTip="Please enter URL">
|
||||
<input type="text" i18n-placeholder placeholder="Enter URL" name="uri" nz-input formControlName="uri"
|
||||
[(ngModel)]="model.request.uri" (change)="changeUri()" />
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<button type="submit" nz-button nzType="primary" class="ml10 w_100" (click)="clickTest()">
|
||||
@ -43,128 +25,88 @@
|
||||
<span *ngIf="status === 'testing'" i18n>Abort</span>
|
||||
<span *ngIf="status === 'testing' && waitSeconds" class="ml-1">{{ waitSeconds }}</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
*ngIf="!route.snapshot.queryParams.uuid || route.snapshot.queryParams.uuid.includes('history_')"
|
||||
nz-button
|
||||
nzType="default"
|
||||
(click)="saveApi()"
|
||||
class="ml10"
|
||||
i18n
|
||||
>
|
||||
<button type="button"
|
||||
*ngIf="!route.snapshot.queryParams.uuid || route.snapshot.queryParams.uuid.includes('history_')" nz-button
|
||||
nzType="default" (click)="saveApi()" class="ml10" i18n>
|
||||
Save as API
|
||||
</button>
|
||||
</nz-input-group>
|
||||
</form>
|
||||
<!-- Request Info -->
|
||||
<nz-tabset
|
||||
[nzTabBarStyle]="{ 'padding-left': '10px' }"
|
||||
[nzAnimated]="false"
|
||||
[(nzSelectedIndex)]="model.requestTabIndex"
|
||||
>
|
||||
<nz-tabset [nzTabBarStyle]="{ 'padding-left': '10px' }" [nzAnimated]="false"
|
||||
[(nzSelectedIndex)]="model.requestTabIndex">
|
||||
<!-- Request Headers -->
|
||||
<nz-tab [nzTitle]="headerTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #headerTitleTmp>
|
||||
<span i18n="@@RequestHeaders">Headers</span>
|
||||
<span class="eo-tab-icon ml-[4px]" *ngIf="bindGetApiParamNum(model.request.requestHeaders)">{{
|
||||
model.request.requestHeaders | apiParamsNum
|
||||
}}</span>
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-test-header
|
||||
class="eo_theme_iblock bbd"
|
||||
[(model)]="model.request.requestHeaders"
|
||||
(modelChange)="emitChangeFun('requestHeaders')"
|
||||
></eo-api-test-header>
|
||||
<eo-api-test-header class="eo_theme_iblock bbd" [(model)]="model.request.requestHeaders"
|
||||
(modelChange)="emitChangeFun('requestHeaders')"></eo-api-test-header>
|
||||
</nz-tab>
|
||||
<!--Request Info -->
|
||||
<nz-tab [nzTitle]="bodyTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #bodyTitleTmp>
|
||||
<span i18n>Body</span>
|
||||
<span
|
||||
class="eo-tab-theme-icon"
|
||||
*ngIf="
|
||||
<span class="eo-tab-theme-icon" *ngIf="
|
||||
['formData', 'json', 'xml'].includes(model.request.requestBodyType)
|
||||
? bindGetApiParamNum(model.request.requestBody)
|
||||
: model.request.requestBody?.length
|
||||
"
|
||||
></span>
|
||||
"></span>
|
||||
</ng-template>
|
||||
<eo-api-test-body
|
||||
class="eo_theme_iblock bbd"
|
||||
[(contentType)]="model.contentType"
|
||||
(contentTypeChange)="changeContentType($event)"
|
||||
[(bodyType)]="model.request.requestBodyType"
|
||||
(bodyTypeChange)="changeBodyType($event)"
|
||||
[(model)]="model.request.requestBody"
|
||||
(modelChange)="emitChangeFun('requestBody')"
|
||||
[supportType]="['formData', 'raw', 'binary']"
|
||||
></eo-api-test-body>
|
||||
<eo-api-test-body class="eo_theme_iblock bbd" [(contentType)]="model.contentType"
|
||||
(contentTypeChange)="changeContentType($event)" [(bodyType)]="model.request.requestBodyType"
|
||||
(bodyTypeChange)="changeBodyType($event)" [(model)]="model.request.requestBody"
|
||||
(modelChange)="emitChangeFun('requestBody')" [supportType]="['formData', 'raw', 'binary']">
|
||||
</eo-api-test-body>
|
||||
</nz-tab>
|
||||
<nz-tab [nzTitle]="queryTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #queryTitleTmp>
|
||||
<span i18n>Query</span>
|
||||
<span class="eo-tab-icon ml-[4px]" *ngIf="bindGetApiParamNum(model.request.queryParams)">{{
|
||||
model.request.queryParams | apiParamsNum
|
||||
}}</span>
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-test-query
|
||||
class="eo_theme_iblock bbd"
|
||||
[model]="model.request.queryParams"
|
||||
(modelChange)="emitChangeFun('queryParams')"
|
||||
></eo-api-test-query>
|
||||
<eo-api-test-query class="eo_theme_iblock bbd" [model]="model.request.queryParams"
|
||||
(modelChange)="emitChangeFun('queryParams')"></eo-api-test-query>
|
||||
</nz-tab>
|
||||
<nz-tab [nzTitle]="restTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #restTitleTmp>
|
||||
<span i18n>REST</span>
|
||||
<span class="eo-tab-icon ml-[4px]" *ngIf="bindGetApiParamNum(model.request.restParams)">{{
|
||||
model.request.restParams | apiParamsNum
|
||||
}}</span>
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-test-rest
|
||||
class="eo_theme_iblock bbd"
|
||||
[(model)]="model.request.restParams"
|
||||
(modelChange)="emitChangeFun('restParams')"
|
||||
></eo-api-test-rest>
|
||||
<eo-api-test-rest class="eo_theme_iblock bbd" [(model)]="model.request.restParams"
|
||||
(modelChange)="emitChangeFun('restParams')"></eo-api-test-rest>
|
||||
</nz-tab>
|
||||
<nz-tab [nzTitle]="preScriptTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #preScriptTitleTmp>
|
||||
<span i18n>Pre-request Script</span>
|
||||
<span class="eo-tab-theme-icon" *ngIf="model.beforeScript?.trim()"></span>
|
||||
</ng-template>
|
||||
<eo-api-script
|
||||
*ngIf="model.requestTabIndex === 4"
|
||||
[(code)]="model.beforeScript"
|
||||
(codeChange)="emitChangeFun('beforeScript')"
|
||||
[treeData]="BEFORE_DATA"
|
||||
[completions]="beforeScriptCompletions"
|
||||
class="eo_theme_iblock bbd"
|
||||
></eo-api-script>
|
||||
<eo-api-script *ngIf="model.requestTabIndex === 4" [(code)]="model.beforeScript"
|
||||
(codeChange)="emitChangeFun('beforeScript')" [treeData]="BEFORE_DATA"
|
||||
[completions]="beforeScriptCompletions" class="eo_theme_iblock bbd"></eo-api-script>
|
||||
</nz-tab>
|
||||
<nz-tab [nzTitle]="suffixScriptTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #suffixScriptTitleTmp>
|
||||
<span i18n>After-response Script</span>
|
||||
<span class="eo-tab-theme-icon" *ngIf="model.afterScript?.trim()"></span>
|
||||
</ng-template>
|
||||
<eo-api-script
|
||||
*ngIf="model.requestTabIndex === 5"
|
||||
[(code)]="model.afterScript"
|
||||
(codeChange)="emitChangeFun('afterScript')"
|
||||
[treeData]="AFTER_DATA"
|
||||
[completions]="afterScriptCompletions"
|
||||
class="eo_theme_iblock bbd"
|
||||
></eo-api-script>
|
||||
<eo-api-script *ngIf="model.requestTabIndex === 5" [(code)]="model.afterScript"
|
||||
(codeChange)="emitChangeFun('afterScript')" [treeData]="AFTER_DATA" [completions]="afterScriptCompletions"
|
||||
class="eo_theme_iblock bbd"></eo-api-script>
|
||||
</nz-tab>
|
||||
</nz-tabset>
|
||||
</div>
|
||||
<div class="bottom_container scroll_container" bottom>
|
||||
<!-- Response -->
|
||||
<nz-tabset
|
||||
[nzTabBarStyle]="{ 'padding-left': '10px' }"
|
||||
[(nzSelectedIndex)]="model.responseTabIndex"
|
||||
[nzAnimated]="false"
|
||||
class="mt-2.5 response_container"
|
||||
(nzSelectChange)="handleBottomTabSelect($event)"
|
||||
>
|
||||
<nz-tabset [nzTabBarStyle]="{ 'padding-left': '10px' }" [(nzSelectedIndex)]="model.responseTabIndex"
|
||||
[nzTabBarExtraContent]="extraTemplate" [nzAnimated]="false" class="mt-2.5 response_container"
|
||||
(nzSelectChange)="handleBottomTabSelect($event)">
|
||||
<nz-tab i18n-nzTitle nzTitle="Response">
|
||||
<eo-api-test-result-response [model]="model.testResult.response"></eo-api-test-result-response>
|
||||
</nz-tab>
|
||||
@ -175,16 +117,21 @@
|
||||
</div>
|
||||
<nz-tab i18n-nzTitle nzTitle="Body" [nzForceRender]="true">
|
||||
<!-- TODO use isRequestBodyLoaded -->
|
||||
<eo-api-test-result-request-body
|
||||
*ngIf="model.responseTabIndex === 2"
|
||||
[model]="model.testResult.request.requestBody || ''"
|
||||
>
|
||||
<eo-api-test-result-request-body *ngIf="model.responseTabIndex === 2"
|
||||
[model]="model.testResult.request.requestBody || ''">
|
||||
</eo-api-test-result-request-body>
|
||||
</nz-tab>
|
||||
<nz-tab i18n-nzTitle nzTitle="Request Headers">
|
||||
<eo-api-test-result-header [model]="model.testResult.request.requestHeaders"> </eo-api-test-result-header>
|
||||
</nz-tab>
|
||||
</nz-tabset>
|
||||
<ng-template #extraTemplate>
|
||||
<div *ngIf="model.responseTabIndex === 0" class="px-[10px]">
|
||||
<!-- <span nz-icon nzType="download" nzTheme="outline">下载</span> -->
|
||||
<a nz-button nzType="link" [disabled]="isEmpty(model.testResult?.response)" (click)="downloadFile()"
|
||||
i18n>Download</a>
|
||||
</div>
|
||||
</ng-template>
|
||||
<div id="test-response"></div>
|
||||
</div>
|
||||
</eo-split-panel>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit, OnDestroy, ChangeDetectorRef, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy, ChangeDetectorRef, Input, Output, EventEmitter, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Select } from '@ngxs/store';
|
||||
@ -33,6 +33,8 @@ import { LanguageService } from 'eo/workbench/browser/src/app/core/services/lang
|
||||
import { ContentTypeByAbridge } from 'eo/workbench/browser/src/app/shared/services/api-test/api-test.model';
|
||||
import { transferUrlAndQuery } from 'eo/workbench/browser/src/app/utils/api';
|
||||
import { getGlobals, setGlobals } from 'eo/workbench/browser/src/app/shared/services/api-test/api-test.utils';
|
||||
import { ApiTestResultResponseComponent } from 'eo/workbench/browser/src/app/pages/api/http/test/result-response/api-test-result-response.component';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
|
||||
const API_TEST_DRAG_TOP_HEIGHT_KEY = 'API_TEST_DRAG_TOP_HEIGHT';
|
||||
interface testViewModel {
|
||||
@ -63,6 +65,7 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
@Output() modelChange = new EventEmitter<testViewModel>();
|
||||
@Output() afterTested = new EventEmitter<any>();
|
||||
@Output() eoOnInit = new EventEmitter<testViewModel>();
|
||||
@ViewChild(ApiTestResultResponseComponent) apiTestResultResponseComponent: ApiTestResultResponseComponent; // 通过组件类型获取
|
||||
@Select(EnvState) env$: Observable<any>;
|
||||
validateForm!: FormGroup;
|
||||
env: any = {
|
||||
@ -83,6 +86,7 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
REQUEST_METHOD = objectToArray(RequestMethod);
|
||||
REQUEST_PROTOCOL = objectToArray(RequestProtocol);
|
||||
MAX_TEST_SECONDS = 60;
|
||||
isEmpty = isEmpty;
|
||||
|
||||
private initTimes = 0;
|
||||
private status$: Subject<string> = new Subject<string>();
|
||||
@ -343,11 +347,11 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
//* Other tab test finish,support multiple tab test same time
|
||||
this.afterTested.emit({
|
||||
id: queryParams.pageID,
|
||||
url:'/home/api/http/test',
|
||||
url: '/home/api/http/test',
|
||||
model: {
|
||||
testStartTime: 0,
|
||||
testResult: tmpHistory,
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.model.testResult = tmpHistory;
|
||||
@ -384,6 +388,9 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
},
|
||||
});
|
||||
}
|
||||
downloadFile() {
|
||||
this.apiTestResultResponseComponent.downloadResponseText();
|
||||
}
|
||||
/**
|
||||
* Change test status
|
||||
*
|
||||
|
@ -19,36 +19,38 @@
|
||||
<nz-alert class="eo_alert_bar" *ngFor="let item of model.reportList"
|
||||
[nzType]="item.type === 'interrupt' ? 'error' : 'info'" [nzMessage]="item.content.toString()" nzShowIcon></nz-alert>
|
||||
<!-- Response -->
|
||||
<div *ngIf="model.responseType" [ngSwitch]="model.responseType">
|
||||
<div class="text-center" *ngSwitchCase="'stream'">
|
||||
<div *ngIf="!responseIsImg">
|
||||
<span i18n>Unable to preview non-text type data, you can</span>
|
||||
<button class="eo_theme_btn_default mlr5" type="button" (click)="downloadResponseText()"
|
||||
i18n="@@downloadResponse">
|
||||
download response
|
||||
</button>
|
||||
<span i18n>and open it with other programs.</span>
|
||||
</div>
|
||||
<div class="mt20" *ngIf="responseIsImg" (contextmenu)="contextMenu($event, menu)">
|
||||
<img class="maw_100percent" [src]="imgBlobUrl" />
|
||||
</div>
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu">
|
||||
<ul nz-menu>
|
||||
<li nz-menu-item i18n="@@downloadResponse" (click)="downloadResponseText()">download response</li>
|
||||
</ul>
|
||||
</nz-dropdown-menu>
|
||||
</div>
|
||||
<div class="text-center" *ngSwitchCase="'longText'">
|
||||
<span i18n>The response result exceeds the previewable size, you can</span>
|
||||
<button i18n="@@downloadResponse" class="eo_theme_btn_default mlr5" type="button"
|
||||
(click)="downloadResponseText()">
|
||||
download response
|
||||
</button>
|
||||
<!-- or
|
||||
<button class="eo_theme_btn_default" type="button" (click)="newTabResponseText()">在新标签页中显示返回结果</button>
|
||||
and open it with other programs. -->
|
||||
</div>
|
||||
<eo-monaco-editor *ngSwitchDefault class="mt20" [autoFormat]="true" [(code)]="model.body"
|
||||
[config]="{ readOnly: true }" [eventList]="['type', 'format', 'copy', 'search']"></eo-monaco-editor>
|
||||
<div *ngIf="model.responseType">
|
||||
<ng-container *ngIf="responseIsImg; else stream">
|
||||
<img class="maw_100percent" [src]="imgBlobUrl" />
|
||||
</ng-container>
|
||||
<ng-template #stream>
|
||||
<ng-container *ngIf="model.responseType === 'stream' && model.responseLength > 500000; else longText">
|
||||
<div class="text-center">
|
||||
<span i18n>Unable to preview non-text type data, you can</span>
|
||||
<button class="eo_theme_btn_default mlr5" type="button" (click)="downloadResponseText()"
|
||||
i18n="@@downloadResponse">
|
||||
download response
|
||||
</button>
|
||||
<span i18n>and open it with other programs.</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
<ng-template #longText>
|
||||
<ng-container *ngIf="model.responseType === 'longText' && model.responseLength > 500000; else other">
|
||||
<div class="text-center">
|
||||
<span i18n>The response result exceeds the previewable size, you can</span>
|
||||
<button i18n="@@downloadResponse" class="eo_theme_btn_default mlr5" type="button"
|
||||
(click)="downloadResponseText()">
|
||||
download response
|
||||
</button>
|
||||
<!-- or
|
||||
<button class="eo_theme_btn_default" type="button" (click)="newTabResponseText()">在新标签页中显示返回结果</button>
|
||||
and open it with other programs. -->
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
<ng-template #other>
|
||||
<eo-monaco-editor class="mt20" [autoFormat]="true" [(code)]="model.body" [config]="{ readOnly: true }"
|
||||
[eventList]="['type', 'format', 'copy', 'search']"></eo-monaco-editor>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -41,7 +41,11 @@ export class ApiTestResultResponseComponent implements OnInit, OnChanges {
|
||||
}
|
||||
}
|
||||
}
|
||||
ngOnInit(): void {}
|
||||
ngOnInit(): void {
|
||||
setTimeout(() => {
|
||||
console.log('this.model', this.model);
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
contextMenu($event: MouseEvent, menu: NzDropdownMenuComponent): void {
|
||||
this.nzContextMenuService.create($event, menu);
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
ElementRef,
|
||||
} from '@angular/core';
|
||||
import { EoMessageService } from 'eo/workbench/browser/src/app/eoui/message/eo-message.service';
|
||||
import { debounce, whatTextType } from '../../../utils';
|
||||
import { debounce, isBase64, whatTextType } from '../../../utils';
|
||||
import { ElectronService } from 'eo/workbench/browser/src/app/core/services/electron/electron.service';
|
||||
import { editor } from 'monaco-editor';
|
||||
import * as monaco from 'monaco-editor';
|
||||
@ -171,11 +171,14 @@ export class EoMonacoEditorComponent implements AfterViewInit, OnInit, OnChanges
|
||||
if (val === this.$$code) {
|
||||
return;
|
||||
}
|
||||
// console.log('val', val);
|
||||
|
||||
let code = '';
|
||||
try {
|
||||
code = JSON.stringify(typeof val === 'string' ? JSON.parse(val) : val, null, 4);
|
||||
if (isBase64(val)) {
|
||||
code = window.atob(val);
|
||||
} else {
|
||||
code = JSON.stringify(typeof val === 'string' ? JSON.parse(val) : val, null, 4);
|
||||
}
|
||||
} catch {
|
||||
code = String(val);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import { NzResizableModule } from 'ng-zorro-antd/resizable';
|
||||
import { NzDividerModule } from 'ng-zorro-antd/divider';
|
||||
import { NzModalModule } from 'ng-zorro-antd/modal';
|
||||
import { NzTypographyModule } from 'ng-zorro-antd/typography';
|
||||
import { NzIconModule } from 'ng-zorro-antd/icon';
|
||||
|
||||
import { NzNotificationModule } from 'ng-zorro-antd/notification';
|
||||
import { NzMessageModule } from 'ng-zorro-antd/message';
|
||||
@ -93,6 +94,7 @@ const SHARED_MODULE = [
|
||||
NzDividerModule,
|
||||
NzModalModule,
|
||||
NzTypographyModule,
|
||||
NzIconModule,
|
||||
] as const;
|
||||
|
||||
@NgModule({
|
||||
|
@ -166,7 +166,7 @@ export function debounce(fn, wait = 50) {
|
||||
let timer = null;
|
||||
// 将 debounce 处理结果当作函数返回
|
||||
// 触发事件回调时执行这个返回函数
|
||||
return function(...args) {
|
||||
return function (...args) {
|
||||
// this保存给context
|
||||
const context = this;
|
||||
// 如果已经设定过定时器就清空上一次的定时器
|
||||
@ -183,7 +183,7 @@ export function debounce(fn, wait = 50) {
|
||||
|
||||
export function throttle(fn, gap) {
|
||||
let timerId = null;
|
||||
return function(...rest) {
|
||||
return function (...rest) {
|
||||
if (timerId === null) {
|
||||
fn(...rest); // 立即执行
|
||||
timerId = setTimeout(() => {
|
||||
@ -232,5 +232,16 @@ export const eoDeepCopy = (obj) => {
|
||||
return copy;
|
||||
}
|
||||
|
||||
throw new Error('Unable to copy obj! Its type isn\'t supported.');
|
||||
throw new Error("Unable to copy obj! Its type isn't supported.");
|
||||
};
|
||||
|
||||
export function isBase64(str) {
|
||||
if (str === '' || str.trim() === '') {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return window.btoa(window.atob(str)) === str;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
34
yarn.lock
34
yarn.lock
@ -302,7 +302,16 @@
|
||||
dependencies:
|
||||
tslib "^2.3.0"
|
||||
|
||||
"@angular/cdk@13.3.9", "@angular/cdk@^13.0.1":
|
||||
"@angular/cdk@14.0.3":
|
||||
version "14.0.3"
|
||||
resolved "https://registry.npmmirror.com/@angular/cdk/-/cdk-14.0.3.tgz#eaa0b0736481bc9c1d24ad88e19dd20874506032"
|
||||
integrity sha512-XN5+WVUFx13lW2x9gnzJprHGqcvSpKQaoXxFvlcn16i0P6Iy1jldVZm6q6chEhgX9rEi7P31nfE88OJzHmkEyw==
|
||||
dependencies:
|
||||
tslib "^2.3.0"
|
||||
optionalDependencies:
|
||||
parse5 "^5.0.0"
|
||||
|
||||
"@angular/cdk@^13.0.1":
|
||||
version "13.3.9"
|
||||
resolved "https://registry.npmmirror.com/@angular/cdk/-/cdk-13.3.9.tgz#a177196e872e29be3f84d3a50f778d361c689ff7"
|
||||
integrity sha512-XCuCbeuxWFyo3EYrgEYx7eHzwl76vaWcxtWXl00ka8d+WAOtMQ6Tf1D98ybYT5uwF9889fFpXAPw98mVnlo3MA==
|
||||
@ -417,9 +426,9 @@
|
||||
tslib "^2.3.0"
|
||||
|
||||
"@angular/upgrade@^14.0.3":
|
||||
version "14.1.0"
|
||||
resolved "https://registry.npmmirror.com/@angular/upgrade/-/upgrade-14.1.0.tgz#e2e4ba33b8dce009e96fc9ece5e4d36061c6ce73"
|
||||
integrity sha512-EOFSpcdncQiQ7A5WktKe4r5uFkEDB325ddqZsuHesMbEQFeFu+93JwJWeRtU9gEyyuVCIDN6DyKaizUw/M4yGA==
|
||||
version "14.2.1"
|
||||
resolved "https://registry.npmmirror.com/@angular/upgrade/-/upgrade-14.2.1.tgz#7e154fb721a1764d0c226ac751fb04912725a78c"
|
||||
integrity sha512-UxmqUBoaSFM28UBDA+heTQwNYrhq0mDdmcMt7Pg1gj0kPaQY3f6NgbrNH2UMnps+b4aZEbD/jnoJ3+I2F3VuhA==
|
||||
dependencies:
|
||||
tslib "^2.3.0"
|
||||
|
||||
@ -2300,6 +2309,18 @@
|
||||
resolved "https://registry.npmmirror.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9"
|
||||
integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==
|
||||
|
||||
"@types/lodash-es@4.17.6":
|
||||
version "4.17.6"
|
||||
resolved "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.6.tgz#c2ed4c8320ffa6f11b43eb89e9eaeec65966a0a0"
|
||||
integrity sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash@*":
|
||||
version "4.14.185"
|
||||
resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.185.tgz#c9843f5a40703a8f5edfd53358a58ae729816908"
|
||||
integrity sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==
|
||||
|
||||
"@types/markdown-it@12.2.3":
|
||||
version "12.2.3"
|
||||
resolved "https://registry.npmmirror.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51"
|
||||
@ -8542,6 +8563,11 @@ lockfile@^1.0.4:
|
||||
dependencies:
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
lodash-es@4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
|
||||
|
||||
lodash._baseuniq@~4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.npmmirror.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
|
||||
|
Loading…
Reference in New Issue
Block a user