Unverified Commit 33d73edb authored by 老广's avatar 老广 Committed by GitHub

Merge pull request #129 from jumpserver/dev

Dev
parents 9388e27a 99ab8e18
......@@ -19,14 +19,15 @@
"assets": [
"src/assets",
"src/static",
"src/theme/default",
"src/favicon.ico"
],
"styles": [
"node_modules/animate.css/animate.min.css",
"node_modules/xterm/dist/xterm.css",
"node_modules/ngx-toastr/toastr.css",
"src/sass/style.scss",
"src/styles.css",
"src/theme.scss",
"src/assets/ztree/awesomeStyle/awesome.css"
],
"scripts": [
......
......@@ -8906,6 +8906,14 @@
"vlq": "^1.0.0"
}
},
"ngx-toastr": {
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-10.2.0.tgz",
"integrity": "sha512-6ASr5bcvQmtNKb4D2VEsQjCXyROq6GwberBWO0bVt+xcBYPUea4aRTgX8in9apX9buaTafzG+h3HlnIraspoPg==",
"requires": {
"tslib": "^1.9.0"
}
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
......
......@@ -38,7 +38,7 @@
"utf-8-validate": "^5.0.2"
},
"dependencies": {
"@angular/animations": "~7.2.0",
"@angular/animations": "^7.2.0",
"@angular/cdk": "^7.3.7",
"@angular/common": "~7.2.0",
"@angular/compiler": "~7.2.0",
......@@ -64,6 +64,7 @@
"neffos.js": "^0.1.19",
"ngx-cookie-service": "^1.0.10",
"ngx-logger": "4.0.4",
"ngx-toastr": "^10.2.0",
"popper.js": "^1.14.7",
"requirejs": "^2.3.5",
"rxjs": "~6.3.3",
......
......@@ -4,6 +4,8 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms'; // <-- NgModel
import {NGXLogger} from 'ngx-logger';
import {HttpClientModule} from '@angular/common/http';
import {CookieService} from 'ngx-cookie-service';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {ToastrModule} from 'ngx-toastr';
import {MAT_LABEL_GLOBAL_OPTIONS} from '@angular/material';
// service
......@@ -26,8 +28,10 @@ import {AssetTreeDialogComponent, ManualPasswordDialogComponent} from './element
BrowserModule,
FormsModule,
HttpClientModule,
BrowserAnimationsModule,
ReactiveFormsModule,
AppRouterModule,
ToastrModule.forRoot(),
...PluginModules
],
declarations: [
......
......@@ -3,6 +3,7 @@ import {MatDialog} from '@angular/material';
import {BehaviorSubject, Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
import {ActivatedRoute} from '@angular/router';
import {ToastrService} from 'ngx-toastr';
import {groupBy} from '@app/utils/common';
import {AppService, HttpService, LogService, NavService, SettingService, TreeFilterService} from '@app/services';
......@@ -48,6 +49,7 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
isLoadTreeAsync: boolean;
filterAssetCancel$: Subject<boolean> = new Subject();
loading = true;
favoriteAssets = [];
constructor(private _appSvc: AppService,
private _treeFilterSvc: TreeFilterService,
......@@ -55,7 +57,8 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
public _logger: LogService,
private activatedRoute: ActivatedRoute,
private _http: HttpService,
private settingSvc: SettingService
private settingSvc: SettingService,
private toastr: ToastrService
) {}
ngOnInit() {
......@@ -105,6 +108,10 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
};
}
this._http.getFavoriteAssets().subscribe(resp => {
this.favoriteAssets = resp.map(i => i.asset);
});
this.loading = true;
this._http.getMyGrantedNodes(this.isLoadTreeAsync, refresh).subscribe(resp => {
this.loading = false;
......@@ -206,6 +213,15 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
return findSSHProtocol;
}
isAssetFavorite() {
const host = this.rightClickSelectNode.meta.asset;
if (!host) {
return false;
}
const assetId = host.id;
return this.favoriteAssets.indexOf(assetId) !== -1;
}
get RMenuList() {
const menuList = [{
'id': 'new-connection',
......@@ -219,6 +235,18 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
'fa': 'fa-file',
'hide': !this.nodeSupportSSH(),
'click': this.connectFileManager.bind(this)
}, {
'id': 'favorite',
'name': 'Favorite',
'fa': 'fa-star-o',
'hide': this.isAssetFavorite(),
'click': this.favoriteAsset.bind(this)
}, {
'id': 'disfavor',
'name': 'Disfavor',
'fa': 'fa-star',
'hide': !this.isAssetFavorite(),
'click': this.favoriteAsset.bind(this)
}];
if (!this.rightClickSelectNode) {
return [];
......@@ -265,6 +293,26 @@ export class ElementAssetTreeComponent implements OnInit, OnDestroy {
window.open(url, '_blank');
}
favoriteAsset() {
const host = this.rightClickSelectNode.meta.asset;
if (!host) {
return false;
}
const assetId = host.id;
if (this.isAssetFavorite()) {
this._http.favoriteAsset(assetId, false).subscribe(() => {
const i = this.favoriteAssets.indexOf(assetId);
this.favoriteAssets.splice(i, 1);
this.toastr.success(translate('Disfavor') + ' ' + translate('success'), '', {timeOut: 2000});
});
} else {
this._http.favoriteAsset(assetId, true).subscribe(() => {
this.favoriteAssets.push(assetId);
this.toastr.success(translate('Favorite') + ' ' + translate('success'), '', {timeOut: 2000});
});
}
}
filterAssets(keyword) {
if (this.isLoadTreeAsync) {
this._logger.debug('Filter assets server');
......
......@@ -107,8 +107,8 @@ export class ElementConnectComponent implements OnInit, OnDestroy {
if (systemUsers.length > 1) {
return new Promise<SystemUser>(resolve => {
const dialogRef = this._dialog.open(AssetTreeDialogComponent, {
height: '200px',
width: '300px',
height: '250px',
width: '500px',
data: {users: systemUserMaxPriority}
});
......
<h1 mat-dialog-title>{{"Found"|trans}} {{data.users.length}} {{"Users "|trans}}</h1>
<mat-form-field style="width: 100%">
<mat-select [(value)]="selected"
[compareWith]="compareFn"
[formControl]="UserSelectControl"
placeholder="{{'Choose a User'|trans}}" required>
<mat-option *ngFor="let u of data.users" value="{{u.id}}">{{u.name}}</mat-option>
</mat-select>
<div style="height: 110px">
<div *ngIf="data.users.length < 5">
<div>
<label>{{'Choose a User'|trans}}: </label>
</div>
<mat-radio-group required [formControl]="UserSelectControl" [(ngModel)]="selected">
<mat-radio-button *ngFor="let u of data.users" value="{{u.id}}"
style="padding-right: 10px">{{u.name}}</mat-radio-button>
</mat-radio-group>
</div>
<div *ngIf="data.users.length >= 5">
<mat-form-field style="width: 100%" >
<mat-select [(value)]="selected"
[compareWith]="compareFn"
[formControl]="UserSelectControl"
placeholder="{{'Choose a User'|trans}}" required>
<mat-option *ngFor="let u of data.users" value="{{u.id}}">{{u.name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<mat-error *ngIf="UserSelectControl.hasError('required')">{{"Please choose a User"|trans}}</mat-error>
</mat-form-field>
</div>
<div style="float: right">
<button mat-raised-button (click)="onNoClick()">{{"Cancel"|trans}}</button>
<button mat-raised-button color="primary" [mat-dialog-close]="selected" cdkFocusInitial>{{"Confirm"|trans}}</button>
......
import {NgModule} from '@angular/core';
import {
// MatAutocompleteModule,
MatAutocompleteModule,
MatButtonModule,
// MatButtonToggleModule,
MatButtonToggleModule,
MatCardModule,
// MatCheckboxModule,
MatCheckboxModule,
MatChipsModule,
// MatDatepickerModule,
MatDatepickerModule,
MatDialogModule,
// MatExpansionModule,
// MatGridListModule,
// MatIconModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
// MatListModule,
// MatMenuModule,
// MatNativeDateModule,
// MatPaginatorModule,
// MatProgressBarModule,
// MatProgressSpinnerModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
// MatRippleModule,
MatRippleModule,
MatSelectModule,
// MatSidenavModule,
// MatSliderModule,
// MatSlideToggleModule,
// MatSnackBarModule,
// MatSortModule,
// MatTableModule,
// MatTabsModule,
// MatToolbarModule,
// MatTooltipModule,
// MatStepperModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatStepperModule,
} from '@angular/material';
import {CdkTableModule} from '@angular/cdk/table';
@NgModule({
exports: [
CdkTableModule,
// MatAutocompleteModule,
MatAutocompleteModule,
MatButtonModule,
// MatButtonToggleModule,
MatButtonToggleModule,
MatCardModule,
// MatCheckboxModule,
MatCheckboxModule,
MatChipsModule,
// MatStepperModule,
// MatDatepickerModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
// MatExpansionModule,
// MatGridListModule,
// MatIconModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
// MatListModule,
// MatMenuModule,
// MatNativeDateModule,
// MatPaginatorModule,
// MatProgressBarModule,
// MatProgressSpinnerModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
// MatRippleModule,
MatRippleModule,
MatSelectModule,
// MatSidenavModule,
// MatSliderModule,
// MatSlideToggleModule,
// MatSnackBarModule,
// MatSortModule,
// MatTableModule,
// MatTabsModule,
// MatToolbarModule,
// MatTooltipModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
]
})
export class MaterialModule {
......
......@@ -3,6 +3,7 @@ import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
import {Browser, DataStore} from '@app/globals';
import {GuacObjAddResp, SystemUser, TreeNode, User as _User} from '@app/model';
import {SettingService} from './setting';
import {getCookie} from '@app/utils/common';
@Injectable()
......@@ -12,23 +13,43 @@ export class HttpService {
constructor(private http: HttpClient, private settingSrv: SettingService) {
}
setOptionsCSRFToken(options) {
const csrfToken = getCookie('csrftoken');
let headers;
if (!options) {
options = {};
}
if (!options.headers) {
headers = new HttpHeaders();
} else {
headers = options.headers;
}
headers = headers.set('X-CSRFToken', csrfToken);
options.headers = headers;
return options;
}
get(url: string, options?: any) {
return this.http.get(url, options);
}
post(url: string, options?: any) {
return this.http.post(url, options);
post(url: string, body: any, options?: any) {
options = this.setOptionsCSRFToken(options);
return this.http.post(url, body, options);
}
put(url: string, options?: any) {
options = this.setOptionsCSRFToken(options);
return this.http.put(url, options);
}
delete(url: string, options?: any) {
options = this.setOptionsCSRFToken(options);
return this.http.delete(url, options);
}
patch(url: string, options?: any) {
options = this.setOptionsCSRFToken(options);
return this.http.patch(url, options);
}
......@@ -88,6 +109,25 @@ export class HttpService {
return this.http.get<Array<SystemUser>>(url);
}
favoriteAsset(assetId: string, favorite: boolean) {
let url: string;
if (favorite) {
url = `/api/v1/assets/favorite-assets/`;
const data = {
asset: assetId
};
return this.post(url, data);
} else {
url = `/api/v1/assets/favorite-assets/?asset=${assetId}`;
return this.delete(url);
}
}
getFavoriteAssets() {
const url = '/api/v1/assets/favorite-assets/';
return this.http.get<Array<any>>(url);
}
getGuacamoleToken(user_id: string, authToken: string) {
const body = new HttpParams()
.set('username', user_id)
......
......@@ -31,3 +31,19 @@ export function newTerminal(fontSize?: number) {
}
});
}
export function getCookie(name: string): string {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
......@@ -76,5 +76,8 @@
"yes": "是",
"no": "否",
"cols": "列数",
"rows": "行数"
"rows": "行数",
"favorite": "收藏",
"disfavor": "取消收藏",
"success": "成功"
}
......@@ -124,3 +124,17 @@ body ::-webkit-scrollbar-thumb {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome !important;
}
#toast-container > .toast-warning:before {
}
#toast-container > .toast-error:before {
}
#toast-container > .toast-info:before {
}
#toast-container > .toast-success:before {
content: "";
}
@import '~@angular/material/theming';
@include mat-core();
$my-teal: (
50: #e0f2f1,
100: #b2dfdb,
200: #80cbc4,
300: #4db6ac,
400: #26a69a,
500: #1ab394,
600: #00897b,
700: #00796b,
800: #00695c,
900: #004d40,
A100: #a7ffeb,
A200: #64ffda,
A400: #1de9b6,
A700: #00bfa5,
contrast: (
50: $dark-primary-text,
100: $dark-primary-text,
200: $dark-primary-text,
300: $dark-primary-text,
400: $dark-primary-text,
500: $light-primary-text,
600: $light-primary-text,
700: $light-primary-text,
800: $light-primary-text,
900: $light-primary-text,
A100: $dark-primary-text,
A200: $dark-primary-text,
A400: $dark-primary-text,
A700: $dark-primary-text,
)
);
$candy-app-primary: mat-palette($my-teal, 500);
$candy-app-accent: mat-palette($my-teal, 500);
// The warn palette is optional (defaults to red).
$candy-app-warn: mat-palette($mat-red);
// Create the theme object (a Sass map containing all of the palettes).
$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);
// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($candy-app-theme);
.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:1px -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:230px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:43px;border-left:1px solid #eee;border-right:1px solid #eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{-webkit-animation-duration:.8s;animation-duration:.8s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment