Commit affb7c45 authored by Tt's avatar Tt

init

parent 9f3a2900
This diff is collapsed.
...@@ -353,64 +353,4 @@ npm start ...@@ -353,64 +353,4 @@ npm start
点击“模板管理” 菜单,找到对应的模板卡片,点击“发布”按钮,在弹出的对话框中选中压缩包,然后点击“确定”,上传完成后,则发布就成功了 点击“模板管理” 菜单,找到对应的模板卡片,点击“发布”按钮,在弹出的对话框中选中压缩包,然后点击“确定”,上传完成后,则发布就成功了
## 常见问题汇总
### 静态资源引用路径写法
css文件里面要带 .. , eg:
```
background-image: url("../../assets/playground-house/bg.jpg");
```
其他的文件(html、ts、resources.js)里路径要开头不带斜杠, eg:
```
src="assets/guess-read/btn.png"
```
### no such file or directory,
出现类似如:
```
Error: ENOENT: no such file or directory, open 'C:/publish/resources/xxxx/v1/index.html'
```
这样的代码时, 请确认新建模板的时候表单填写的“配置页面URL”与“展示页面URL” 填写的路径是否正确
### 已经发布的模板,制作课件时看不到
如果模板已经确认发布成功了,制作课件的时候却看不到这个模板,请编辑模板,查看模板类型是否选择为“课中模板”
### 有些模板上传图片或视频时,存在偶尔上传不上去的问题
此问题是因为有些异步的情况下 uploadUrl 获取不到导致的
在 constructor 或者 ngOnInit 方法里,一直轮询,直到获取到 uploadUrl
```
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
const fun = () => {
setTimeout(() => {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
if(!this.uploadUrl){
fun();
}
}, 1000);
}
if(!this.uploadUrl){
fun();
}
```
### 模板编译CI不通过,报类似如下错误
```
ERROR in ./src/styles.scss Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js): Error: Node Sass version 5.0.0 is incompatible with ^4.0.0. at getSassImplementation
```
此情况属于老的模板遗留问题,需要在package.json里面锁一下node-sass的版本
```
"node-sass": "4.0.0"
```
\ No newline at end of file
Angular项目开发AI协作提示词模板
技术栈声明
1. 核心框架:Angular
2. 框架组件: 均在项目根目录下的 src/app/common 目录下
3. 需要操作的代码为: src/app/form/form.component.html 和 src/app/form/form.component.ts
需求描述框架
[模块名称]
- 功能目标:使用Angular开发一个表单组件,包含文本输入框和音频上传功能。
- 技术约束:优先使用框架组件,避免使用外部的第三方组件
- 预期输出:代码尽可能简单,避免使用复杂的逻辑
交互规范
当回答技术问题时:
1. 脚本代码必须给出TypeScript实现方案
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
} }
], ],
"styles": [ "styles": [
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css", "node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.css" "src/styles.css"
], ],
"scripts": [] "scripts": []
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
"src/assets" "src/assets"
], ],
"styles": [ "styles": [
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css", "node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.css" "src/styles.css"
], ],
"scripts": [] "scripts": []
...@@ -128,5 +128,8 @@ ...@@ -128,5 +128,8 @@
} }
} }
}, },
"defaultProject": "ng-template-generator" "defaultProject": "ng-template-generator",
"cli": {
"analytics": "0bdaa560-1d2a-46f5-b14c-1f80decb439e"
}
} }
\ No newline at end of file
This diff is collapsed.
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
"spark-md5": "^3.0.0", "spark-md5": "^3.0.0",
"tslib": "^1.10.0", "tslib": "^1.10.0",
"zone.js": "~0.10.2", "zone.js": "~0.10.2",
"node-sass": "4.0.0" "node-sass": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.900.3", "@angular-devkit/build-angular": "~0.900.3",
......
import { ErrorHandler } from '@angular/core';
export class MyErrorHandler implements ErrorHandler {
handleError(error) {
console.log(error.stack);
(<any> window).courseware.sendErrorLog(error);
}
}
\ No newline at end of file
...@@ -5,12 +5,12 @@ import { Component , OnInit} from '@angular/core'; ...@@ -5,12 +5,12 @@ import { Component , OnInit} from '@angular/core';
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'] styleUrls: ['./app.component.scss']
}) })
export class AppComponent implements OnInit { export class AppComponent implements OnInit{
type = 'play'; type = 'play';
constructor() { constructor() {
const tp = this.getQueryString('type'); let tp = this.getQueryString("type");
if (tp) { if (tp){
this.type = tp; this.type = tp;
} }
} }
......
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ErrorHandler } from '@angular/core';
import {MyErrorHandler} from './MyError';
import { AppComponent } from './app.component'; import { BrowserModule } from '@angular/platform-browser';
import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { AppComponent } from './app.component';
import { FormComponent } from './form/form.component';
import { PlayComponent } from "./play/play.component";
import { LessonTitleConfigComponent } from './common/lesson-title-config/lesson-title-config.component';
import { AudioRecorderComponent } from './common/audio-recorder/audio-recorder.component';
import { PlayerContentWrapperComponent } from './common/player-content-wrapper/player-content-wrapper.component';
/** 配置 angular i18n **/
import { registerLocaleData } from '@angular/common'; import { registerLocaleData } from '@angular/common';
import zh from '@angular/common/locales/zh'; import zh from '@angular/common/locales/zh';
import {FormComponent} from './form/form.component'; import {UploadImageWithPreviewComponent} from "./common/upload-image-with-preview/upload-image-with-preview.component";
import {PlayComponent} from './play/play.component'; import {BackgroundImagePipe} from "./pipes/background-image.pipe";
import {LessonTitleConfigComponent} from './common/lesson-title-config/lesson-title-config.component'; import {UploadVideoComponent} from "./common/upload-video/upload-video.component";
import {BackgroundImagePipe} from './pipes/background-image.pipe'; import {ResourcePipe} from "./pipes/resource.pipe";
import {UploadImageWithPreviewComponent} from './common/upload-image-with-preview/upload-image-with-preview.component'; import {TimePipe} from "./pipes/time.pipe";
import {PlayerContentWrapperComponent} from './common/player-content-wrapper/player-content-wrapper.component'; import {CustomHotZoneComponent} from "./common/custom-hot-zone/custom-hot-zone.component";
import {CustomHotZoneComponent} from './common/custom-hot-zone/custom-hot-zone.component'; registerLocaleData(zh);
import {UploadVideoComponent} from './common/upload-video/upload-video.component';
import {TimePipe} from './pipes/time.pipe';
import {ResourcePipe} from './pipes/resource.pipe';
import {AudioRecorderComponent} from './common/audio-recorder/audio-recorder.component';
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome'; import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { fas } from '@fortawesome/free-solid-svg-icons'; import { fas } from '@fortawesome/free-solid-svg-icons';
import { far } from '@fortawesome/free-regular-svg-icons'; import { far } from '@fortawesome/free-regular-svg-icons';
registerLocaleData(zh);
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -40,20 +45,18 @@ registerLocaleData(zh); ...@@ -40,20 +45,18 @@ registerLocaleData(zh);
TimePipe, TimePipe,
UploadVideoComponent, UploadVideoComponent,
CustomHotZoneComponent, CustomHotZoneComponent,
PlayerContentWrapperComponent PlayerContentWrapperComponent
], ],
imports: [ imports: [
BrowserModule,
NgZorroAntdModule,
FormsModule, FormsModule,
HttpClientModule, HttpClientModule,
BrowserAnimationsModule, BrowserAnimationsModule,
BrowserModule,
NgZorroAntdModule,
FontAwesomeModule FontAwesomeModule
], ],
providers: [ /** 配置 ng-zorro-antd 国际化(文案 及 日期) **/
{provide: ErrorHandler, useClass: MyErrorHandler}, providers : [
{ provide: NZ_I18N, useValue: zh_CN } { provide: NZ_I18N, useValue: zh_CN }
], ],
bootstrap: [AppComponent] bootstrap: [AppComponent]
......
<div class="d-flex"> <div class="d-flex">
<div class="p-btn-record d-flex"> <div class="p-btn-record d-flex">
<div class="btn-clear" style="cursor: pointer" (click)="onBtnClearAudio()" *ngIf="withRmBtn && (audioUrl || audioBlob)"> <div
<fa-icon icon="times"></fa-icon> class="btn-clear"
(click)="onBtnClearAudio()"
*ngIf="withRmBtn && (audioUrl || audioBlob)"
>
<fa-icon name="close"></fa-icon>
</div> </div>
<div class="btn-record" *ngIf="type===Type.RECORD && !isUploading" <div
class="btn-record"
*ngIf="type === Type.RECORD && !isUploading"
[class.p-recording]="isRecording" [class.p-recording]="isRecording"
(click)="onBtnRecord()"> (click)="onBtnRecord()"
<fa-icon icon="microphone"></fa-icon> >
<i nz-icon nzType="audio" nzTheme="outline"></i>
Record Audio Record Audio
</div> </div>
<nz-upload <nz-upload
[nzAccept] = "'.mp3'" [nzAccept]="'.mp3'"
[nzShowUploadList]="false" [nzShowUploadList]="false"
[nzAction]="uploadUrl" [nzAction]="uploadUrl"
[nzData]="uploadData" [nzData]="uploadData"
(nzChange)="handleChange($event)"> (nzChange)="handleChange($event)"
>
<div class="btn-upload" [ngClass]="{'has-clear': withRmBtn && (audioUrl || audioBlob)}" *ngIf="type===Type.UPLOAD && !isUploading"> <div
<fa-icon icon="upload"></fa-icon> class="btn-upload ng-star-inserted"
[ngClass]="{ 'has-clear': withRmBtn && (audioUrl || audioBlob) }"
*ngIf="type === Type.UPLOAD && !isUploading"
>
<i nz-icon nzType="cloud-upload" nzTheme="outline"></i>
Upload Audio Upload Audio
</div> </div>
</nz-upload> </nz-upload>
<div class="p-upload-progress-bg" *ngIf="isUploading"> <div class="p-upload-progress-bg" *ngIf="isUploading">
<div class="i-bg" [style.width]="progress+'%'"></div> <div class="i-bg" [style.width]="progress + '%'"></div>
<div class="i-text"> <div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon> <i nz-icon nzType="loading" nzTheme="outline"></i>
Uploading... Uploading...
</div> </div>
</div> </div>
<div
*ngIf="audioUrl && needRemove; then truthyTemplate; else falsyTemplate"
></div>
<div *ngIf="audioUrl && needRemove; then truthyTemplate else falsyTemplate"></div> <ng-template #truthyTemplate>
<ng-template #truthyTemplate >
<div class="btn-delete" (click)="onBtnDeleteAudio()"> <div class="btn-delete" (click)="onBtnDeleteAudio()">
<fa-icon icon="close"></fa-icon> <i nz-icon nzType="close" nzTheme="outline"></i>
</div> </div>
</ng-template> </ng-template>
<ng-template #falsyTemplate> <ng-template #falsyTemplate>
<div class="btn-switch" (click)="onBtnSwitchType()"> <div class="btn-switch" (click)="onBtnSwitchType()">
<fa-icon icon="cog"></fa-icon> <i nz-icon nzType="setting" nzTheme="outline"></i>
</div> </div>
</ng-template> </ng-template>
</div> </div>
<div class="p-progress ml-2" (click)="onBtnPlay()" *ngIf="audioUrl || audioBlob"> <div
<nz-progress [nzPercent]="percent" [nzWidth]="30" [nzFormat]="progressText" class="p-progress ml-2"
nzType="circle"></nz-progress> (click)="onBtnPlay()"
<div class="p-btn-play" [style.left]="isPlaying?'8px':''"> *ngIf="audioUrl || audioBlob"
<fa-icon [icon]="playIcon"></fa-icon> >
<nz-progress
[nzPercent]="percent"
[nzWidth]="30"
[nzFormat]="progressText"
nzType="circle"
></nz-progress>
<div class="p-btn-play" [style.left]="isPlaying ? '8px' : ''">
<i nz-icon nzType="caret-right" nzTheme="outline"></i>
</div> </div>
</div> </div>
</div> </div>
.d-flex{
display: flex;
}
.p-btn-record { .p-btn-record {
font-size: 0.9rem; font-size: 0.9rem;
color: #555; color: #555;
...@@ -91,6 +88,7 @@ ...@@ -91,6 +88,7 @@
.p-progress { .p-progress {
margin-top: 2px; margin-top: 2px;
margin-left: 5px;
position: relative; position: relative;
line-height: 26px; line-height: 26px;
.p-btn-play { .p-btn-play {
...@@ -105,3 +103,6 @@ ...@@ -105,3 +103,6 @@
line-height: 33px; line-height: 33px;
} }
.d-flex{
display: flex;
}
\ No newline at end of file
...@@ -19,11 +19,10 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -19,11 +19,10 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
isUploading = false; isUploading = false;
type = Type.UPLOAD; // record | upload type = Type.UPLOAD; // record | upload
Type = Type; Type = Type;
@Input()
withRmBtn = false; withRmBtn = false;
uploadUrl; uploadUrl = (<any>window).courseware.uploadUrl();
uploadData; uploadData = (<any>window).courseware.uploadData();
@Input() @Input()
needRemove = false; needRemove = false;
...@@ -33,7 +32,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -33,7 +32,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
@Input() @Input()
set audioUrl(url) { set audioUrl(url) {
this._audioUrl = url; this._audioUrl = url
if (url) { if (url) {
this.audio.src = this._audioUrl; this.audio.src = this._audioUrl;
this.audio.load(); this.audio.load();
...@@ -55,13 +54,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -55,13 +54,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
constructor( private nzMessageService: NzMessageService ) { constructor( private nzMessageService: NzMessageService ) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
window['air'].getUploadCallback = (url, data) => {
this.uploadUrl = url;
this.uploadData = data;
};
} }
init() { init() {
...@@ -151,7 +144,6 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -151,7 +144,6 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
onBtnSwitchType() { onBtnSwitchType() {
} }
onBtnClearAudio() { onBtnClearAudio() {
this.audioUrl = null;
this.audioRemoved.emit(); this.audioRemoved.emit();
} }
...@@ -194,7 +186,6 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -194,7 +186,6 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
return true; return true;
} }
beforeUpload = (file: File) => { beforeUpload = (file: File) => {
this.audioUrl = null; this.audioUrl = null;
if (!this.checkSelectFile(file)) { if (!this.checkSelectFile(file)) {
return false; return false;
...@@ -205,7 +196,11 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -205,7 +196,11 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
uploadSuccess = (url) => { uploadSuccess = (url) => {
this.nzMessageService.info('Upload Success'); this.nzMessageService.info('Upload Success');
this.isUploading = false; this.isUploading = false;
this.audioUrl = url; if(typeof url == "string"){
this.audioUrl = url
}else{
this.audioUrl = url.url
}
} }
uploadFailure = (err, file) => { uploadFailure = (err, file) => {
this.isUploading = false; this.isUploading = false;
......
This diff is collapsed.
<div class="p-image-children-editor"> <div class="p-image-children-editor">
<h5 style="margin-left: 2.5%;"> preview: </h5> <div style="float: left; width: 25%;border-right: 2px solid #ddd; border-bottom: 2px solid #ddd;">
<h5 style="margin-left: 2.5%;">预览:</h5>
<div class="preview-box" #wrap> <div id="canvas-container" style="margin:5px;">
<div class="preview-box" #wrap style="margin-bottom: 20px">
<canvas id="canvas" #canvas></canvas> <canvas id="canvas" #canvas></canvas>
</div> </div>
</div>
<div nz-row nzType="flex" nzAlign="middle"> <div style="text-align: center">
<div nz-col nzSpan="5" nzOffset="1"> <button nz-button nzType="primary" [nzSize]="'small'" nzShape="round" (click)="saveClick()" [disabled]="!hotZoneChanged" >
<i nz-icon type="save"></i>
<h5> add background: </h5> Save
</button>
</div>
<h5 style="border-top: 2px solid #ddd;">背景图:</h5>
<div style="width: 200px;margin: auto;">
<div class="bg-box"> <div class="bg-box">
<app-upload-image-with-preview <app-upload-image-with-preview
[picUrl]="bgItem?.url" [picUrl]="bgItem.url"
(imageUploaded)="onBackgroundUploadSuccess($event)"> (imageUploaded)="onBackgroundUploadSuccess($event)"
>
</app-upload-image-with-preview> </app-upload-image-with-preview>
</div> </div>
</div> </div>
<div nz-col nzSpan="5" nzOffset="1" class="img-box"
*ngFor="let it of hotZoneArr; let i = index">
<div
style="margin: auto; padding: 5px; margin-top: 30px; width:90%; border: 2px dashed #ddd; border-radius: 10px">
<span style="margin-left: 40%;"> item-{{i + 1}}
</span>
<button style="float: right;" nz-button nzType="danger" nzSize="small" (click)="deleteBtnClick(i)">
X
</button>
<nz-divider style="margin-top: 10px;"></nz-divider>
<div style="margin-top: -20px; margin-bottom: 5px">
<nz-radio-group [ngModel]="it.itemType" (ngModelChange)="radioChange($event, it)">
<label *ngIf="isHasRect" nz-radio nzValue="rect">矩形</label>
<label *ngIf="isHasPic" nz-radio nzValue="pic">图片</label>
<label *ngIf="isHasText" nz-radio nzValue="text">文本</label>
</nz-radio-group>
</div> </div>
<div *ngIf="it.itemType == 'pic'"> <div style="float: left; width: 75%">
<app-upload-image-with-preview <div nzAlign="middle">
[picUrl]="it?.pic_url" <div class="img-box clearfix" *ngFor="let it of hotZoneArr; let i = index" style="border-bottom: 1px solid #DDD; padding-bottom: 10px;" >
(imageUploaded)="onItemImgUploadSuccess($event, it)"> <div style="float: left; height: 115px; position: relative; width: 250px; ">
</app-upload-image-with-preview> <h3> 第-{{ i + 1 }}-题 </h3>
<div style="position: absolute; bottom: 0;">
<h5> 题目音频 </h5>
<app-audio-recorder [audioUrl]="it.audio_url ? it.audio_url : null" (audioUploaded)="onAudioUploadSuccess($event, it, false)" ></app-audio-recorder>
</div> </div>
<div *ngIf="it.itemType == 'text'">
<input type="text" nz-input [(ngModel)]="it.text" (blur)="saveText(it)">
</div> </div>
<div style="float: left; height: 115px; position: relative; width: 250px; ">
<div style="width: 100%; margin-top: 5px;"> <div style="position: absolute; bottom: 0;">
<app-audio-recorder <h5> 卡片音频 </h5>
[audioUrl]="it.audio_url" <app-audio-recorder [audioUrl]="it.card_audio_url ? it.card_audio_url : null" (audioUploaded)="onAudioUploadSuccess($event, it, true)" ></app-audio-recorder>
(audioUploaded)="onItemAudioUploadSuccess($event, it)" </div>
></app-audio-recorder> </div>
<div style="float: left;">
<div style="width:200px">
<app-upload-image-with-preview [picUrl]="it.image_url" (imageUploaded)="onImgUploadSuccessByImg($event, it)" ></app-upload-image-with-preview>
</div> </div>
</div> </div>
<div style="float: left; display: flex; flex-direction: column; padding-left: 10px;">
<button style="flex:1; margin-bottom: 5px;" nz-button nzType="dashed" (click)="handleMoveItemUp($event, i)" [disabled]="i==0">
<i nz-icon nzType="up" nzTheme="outline"></i>
上移
</button>
<button style="flex:1; margin-bottom: 5px;" nz-button nzType="dashed" (click)="handleMoveItemDown($event, i)" [disabled]="i==hotZoneArr.length-1">
<i nz-icon nzType="down" nzTheme="outline"></i>
下移
</button>
<button style="flex:1; margin-bottom: 5px;" nz-button nzType="danger" (click)="deleteItem($event, i)">
<i nz-icon nzType="delete" nzTheme="outline"></i>
删除
</button>
</div> </div>
</div>
<div nz-col nzSpan="5" nzOffset="1"> <div nz-col nzSpan="5" nzOffset="1">
<div class="bg-box"> <div class="bg-box">
<button nz-button nzType="dashed" (click)="addBtnClick()" <button
class="add-btn"> nz-button
nzType="dashed"
(click)="addBtnClick()"
class="add-btn"
>
<i nz-icon nzType="plus-circle" nzTheme="outline"></i> <i nz-icon nzType="plus-circle" nzTheme="outline"></i>
<!--Add Image--> <!--Add Image-->
Add hot zone Add hot zone
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div>
<nz-divider></nz-divider> <nz-divider></nz-divider>
<div class="save-box"> <div class="save-box">
<button class="save-btn" nz-button nzType="primary" [nzSize]="'large'" nzShape="round"
(click)="saveClick()" >
<i nz-icon nzType="save"></i>
Save
</button>
</div> </div>
</div> </div>
<label style="opacity: 0; position: absolute; top: 0px; font-family: 'BRLNSR_1'">1</label>
.p-image-children-editor { .p-image-children-editor {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 0.5rem; border-radius: 0.5rem;
min-width: 1200px;
border: 2px solid #ddd; border: 2px solid #ddd;
.preview-box { .preview-box {
margin: auto; margin: auto;
width: 95%; width: 100%;
height: 35vw; // height: 35vw;
border: 2px dashed #ddd; border: 2px dashed #ddd;
border-radius: 0.5rem; border-radius: 0.5rem;
background-color: #fafafa; background-color: #fafafa;
text-align: center; text-align: center;
color: #aaa; color: #aaa;
.preview-img { .preview-img {
height: 100%; height: 100%;
width: auto; width: auto;
} }
} }
.bg-box {
.bg-box{
//width: 100%;
margin-bottom: 1rem; margin-bottom: 1rem;
}
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
} }
.img-box { .img-box {
margin-bottom: 1rem; margin: 1rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
} }
.img-box-upload{ .img-box-upload {
width: 80%; width: 120px;
height: 80px;
} }
.add-btn { .add-btn {
margin-top: 1rem; margin-top: 1rem;
width: 200px; width: 200px;
height: 90px; height: 90px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
} }
.save-box { .save-box {
width: 100%; width: 100%;
...@@ -85,28 +72,6 @@ h5 { ...@@ -85,28 +72,6 @@ h5 {
margin-top: 1rem; margin-top: 1rem;
} }
@font-face
{
font-family: 'BRLNSR_1';
src: url("/assets/font/BRLNSR_1.TTF") ;
}
//@import '../../../style/common_mixin'; //@import '../../../style/common_mixin';
// //
//.p-image-uploader { //.p-image-uploader {
......
<div class="title-config"> <div class="title-config">
<div class="title-wrap"> <div class="title-wrap">
...@@ -8,10 +7,9 @@ ...@@ -8,10 +7,9 @@
<nz-select class="ml-1" style="width: 120px;" [(ngModel)]="__fontFamily" <nz-select class="ml-1" style="width: 120px;" [(ngModel)]="__fontFamily"
(ngModelChange)="onChangeFontFamily($event)" (ngModelChange)="onChangeFontFamily($event)"
nzPlaceHolder="Font Family" nzPlaceHolder="Font Family"
[nzDropdownMatchSelectWidth]="false"> [nzDropdownMatchSelectWidth]="false"
<nz-option [nzValue]="font" nzCustomContent [nzLabel]="font" *ngFor="let font of fontFamilyList"> >
<span [ngStyle]="{'font-family': font}" >{{font}}</span> <nz-option [nzValue]="font" [nzLabel]="font" *ngFor="let font of fontFamilyList"></nz-option>
</nz-option>
</nz-select> </nz-select>
<nz-select class="ml-1" style="width: 110px;" [(ngModel)]="__fontSize" <nz-select class="ml-1" style="width: 110px;" [(ngModel)]="__fontSize"
(ngModelChange)="onChangeFontSize()" (ngModelChange)="onChangeFontSize()"
...@@ -21,33 +19,28 @@ ...@@ -21,33 +19,28 @@
<div class="p-divider"></div> <div class="p-divider"></div>
<div class="i-tool-font-btn d-flex mr-2"> <div class="i-tool-font-btn d-flex mr-2">
<div class="position-relative fa-icon" (click)="onChangeBold()"> <div class="position-relative fa-icon" (click)="onChangeBold()">
<!-- <div class="fa fa-bold"></div>--> <div class="fa fa-bold"></div>
<fa-icon icon="bold"></fa-icon>
</div> </div>
</div> </div>
<div class="i-tool-font-btn d-flex mr-2"> <div class="i-tool-font-btn d-flex mr-2">
<div class="position-relative fa-icon" (click)="onChangeItalic()"> <div class="position-relative fa-icon" (click)="onChangeItalic()">
<!-- <div class="fa fa-italic"></div>--> <div class="fa fa-italic"></div>
<fa-icon icon="italic"></fa-icon>
</div> </div>
</div> </div>
<div class="i-tool-font-btn d-flex mr-2"> <div class="i-tool-font-btn d-flex mr-2">
<div class="position-relative fa-icon" (click)="onChangeUnderline()"> <div class="position-relative fa-icon" (click)="onChangeUnderline()">
<!-- <div class="fa fa-underline"></div>--> <div class="fa fa-underline"></div>
<fa-icon icon="underline"></fa-icon>
</div> </div>
</div> </div>
<div class="i-tool-font-btn d-flex"> <div class="i-tool-font-btn d-flex">
<div class="position-relative fa-icon" (click)="onChangeStrikethrough()"> <div class="position-relative fa-icon" (click)="onChangeStrikethrough()">
<!-- <div class="fa fa-strikethrough"></div>--> <div class="fa fa-strikethrough"></div>
<fa-icon icon="strikethrough"></fa-icon>
</div> </div>
</div> </div>
<div class="p-divider"></div> <div class="p-divider"></div>
<div class="i-tool-font-color d-flex"> <div class="i-tool-font-color d-flex">
<div class="position-relative i-left flex-fill" (click)="onChangeFontColor($event)"> <div class="position-relative i-left flex-fill" (click)="onChangeFontColor($event)">
<!-- <div class="fa fa-font"></div>--> <div class="fa fa-font"></div>
<fa-icon icon="palette"></fa-icon>
<div class="i-color" [style.background-color]="__fontColor"></div> <div class="i-color" [style.background-color]="__fontColor"></div>
</div> </div>
<div class="i-dropdown-menu" nzPlacement="bottom" <div class="i-dropdown-menu" nzPlacement="bottom"
...@@ -58,14 +51,14 @@ ...@@ -58,14 +51,14 @@
</div> </div>
<div class="p-divider"></div> <div class="p-divider"></div>
<div style="background: #fff;display: block;"> <div style="background: #fff;display: block;">
<div class="position-relative"> <div class="position-relative" (click)="onChangeStrikethrough()">
<app-audio-recorder [audioUrl]="titleObj && titleObj.audio_url" (audioUploaded)="titleAudioUploaded($event)"></app-audio-recorder> <app-audio-recorder [audioUrl]="titleObj && titleObj.audio_url" (audioUploaded)="titleAudioUploaded($event)"></app-audio-recorder>
</div> </div>
</div> </div>
</div> </div>
<div class="width-100 d-flex"> <div class="width-100 d-flex">
<iframe #titleEl id="titleContentEgret" frameborder="0" style="overflow: hidden;width: 100%; height:48px; margin: 0; padding: 0;"></iframe> <iframe #titleEl frameborder="0" style="overflow: hidden;width: 100%; height:48px; margin: 0; padding: 0;"></iframe>
</div> </div>
</div> </div>
...@@ -83,11 +76,37 @@ ...@@ -83,11 +76,37 @@
<ng-container *ngIf="withIcon">
<div class="row type-row">
课程类型:
<nz-radio-group [(ngModel)]="titleObj && titleObj.type" (ngModelChange)="typeChange($event)">
<label nz-radio nzValue="a">单数课</label>
<label nz-radio nzValue="b">双数课</label>
<label nz-radio nzValue="c">复习课</label>
</nz-radio-group>
</div>
</ng-container>
</div> </div>
<ng-container *ngIf="withIcon">
<div class="title-icons">
<div class="icons-list">
<nz-checkbox-wrapper style="width: 100%;clear:both" (nzOnChange)="iconsChanges($event)">
<div [class]="'icon-item icon-'+i" *ngFor="let i of groupIconsCount[titleObj.type];">
<div class="img-box">
<nz-badge class="icon-badge" [nzCount]="titleObj && titleObj.icons && titleObj.icons.indexOf(i) + 1">
<img [src]="'assets/title-icons/'+titleObj.type+'/icon-'+i+'.png'" alt="">
</nz-badge>
</div>
<label nz-checkbox [nzValue]="i" [ngModel]="titleObj && titleObj.icons && titleObj.icons.indexOf(i) > -1"></label>
</div>
</nz-checkbox-wrapper>
</div>
</div>
</ng-container>
</div> </div>
@import '../../style/common_mixin.css'; @import '../../style/common_mixin';
.title-config { .title-config {
.letter-wrap{ .letter-wrap{
...@@ -11,73 +11,39 @@ ...@@ -11,73 +11,39 @@
.type-row{ .type-row{
margin: 0;padding-top: 1rem; margin: 0;padding-top: 1rem;
} }
.icon-item{
} margin-right: 16px;
@font-face float: left;
{ width: 45px;
font-family: 'BRLNSDB'; height: 75px;
src: url("../../../assets/font/BRLNSDB.TTF") ; display: flex;
} justify-content: center;
align-items: center;
@font-face position: relative;
{ .icon-badge{
font-family: 'BRLNSB'; position: absolute;
src: url("../../../assets/font/BRLNSB.TTF") ; top: 0;
} right: 0;
}
@font-face .img-box{
{ top: 0;
font-family: 'BRLNSR'; position: absolute;
src: url("../../../assets/font/BRLNSR.TTF") ; width: 45px;
} height: 50px;
display: flex;
@font-face justify-content: center;
{ align-items: center;
font-family: 'GOTHIC'; img{
src: url("../../../assets/font/GOTHIC.TTF") ; max-width: 100%;
} }
}
@font-face label{
{ position: absolute;
font-family: 'GOTHICB'; bottom: 0;
src: url("../../../assets/font/GOTHICB.TTF") ; }
} }
@font-face
{
font-family: 'GOTHICBI';
src: url("../../../assets/font/GOTHICBI.TTF") ;
}
@font-face
{
font-family: 'GOTHICI';
src: url("../../../assets/font/GOTHICI.TTF") ;
}
@font-face
{
font-family: 'MMTextBook';
src: url("../../../assets/font/MMTextBook.otf") ;
}
@font-face
{
font-family: 'MMTextBook-Bold';
src: url("../../../assets/font/MMTextBook-Bold.otf") ;
}
@font-face
{
font-family: 'MMTextBook-BoldItalic';
src: url("../../../assets/font/MMTextBook-BoldItalic.otf") ;
} }
@font-face
{
font-family: 'MMTextBook-Italic';
src: url("../../../assets/font/MMTextBook-Italic.otf") ;
}
@mixin tool-btn { @mixin tool-btn {
border: 1px solid #ddd; border: 1px solid #ddd;
display: flex; display: flex;
...@@ -88,37 +54,16 @@ ...@@ -88,37 +54,16 @@
border-radius: 6px; border-radius: 6px;
color: #555; color: #555;
} }
.d-flex{
display: flex;
}
.position-relative { .p-title-box {
position: relative; .p-title {
}
.flex-fill {
-webkit-box-flex: 1;
flex: 1 1 auto;
justify-content: center;
display: flex;
}
.i-dropdown-menu{
width: 15px;
font-size: 10px;
border-left: 1px solid #ddd;
display: -webkit-box;
display: flex;
-webkit-box-align: center;
align-items: center;
flex: 0
}
.p-title-box .p-title {
font-size: 20px; font-size: 20px;
} }
.p-title-box input { input {
width: 300px; width: 300px;
margin-left: 10px; margin-left: 10px;
} }
}
.p-content { .p-content {
border: 1px solid #ddd; border: 1px solid #ddd;
...@@ -140,31 +85,33 @@ ...@@ -140,31 +85,33 @@
align-items: center; align-items: center;
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
// save
.i-tool-save {
} @include tool-btn();
// save
.i-tool-save {
//@include tool-btn();
color: white; color: white;
} }
.i-tool-save:disabled { .i-tool-save:disabled {
color: #555; color: #555;
} }
// font-size // font-size
.i-tool-font-size { .i-tool-font-size {
//@include tool-btn(); @include tool-btn();
width: 37px; width: 37px;
} & > span {
.i-tool-font-size:hover { position: absolute;
top: -5px;
right: 5px;
}
}
.i-tool-font-size:hover {
color: black; color: black;
border-color: #bbb; border-color: #bbb;
} }
// font-color // font-color
.i-tool-font-color, .i-tool-font-btn { .i-tool-font-color, .i-tool-font-btn {
border: 1px solid #ddd; border: 1px solid #ddd;
//padding: 3px 7px; //padding: 3px 7px;
border-radius: 6px; border-radius: 6px;
...@@ -208,20 +155,20 @@ ...@@ -208,20 +155,20 @@
transform: scale(0.6); transform: scale(0.6);
} }
} }
} }
.i-tool-font-btn{ .i-tool-font-btn{
width: 31px; width: 31px;
} }
.fa-icon{ .fa-icon{
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
} }
// bg-color // bg-color
.i-tool-bg-color { .i-tool-bg-color {
@include tool-btn(); @include tool-btn();
padding: 0 9px; padding: 0 9px;
::ng-deep > span { ::ng-deep > span {
...@@ -236,14 +183,17 @@ ...@@ -236,14 +183,17 @@
background-color: white; background-color: white;
margin-left: 10px; margin-left: 10px;
} }
} }
// horizontal-center // horizontal-center
.i-tool-horizontal-center { .i-tool-horizontal-center {
@include tool-btn(); @include tool-btn();
width: 37px; width: 37px;
}
} }
.p-box { .p-box {
width: 1280px; width: 1280px;
height: 720px; height: 720px;
...@@ -253,7 +203,9 @@ ...@@ -253,7 +203,9 @@
overflow: hidden; overflow: hidden;
} }
.p-sentence {
@include k-no-select();
}
.p-animation-index-box { .p-animation-index-box {
.i-animation-index { .i-animation-index {
...@@ -326,6 +278,7 @@ ...@@ -326,6 +278,7 @@
::ng-deep .ant-radio-button-wrapper { ::ng-deep .ant-radio-button-wrapper {
padding: 0 10px; padding: 0 10px;
@include k-no-select();
} }
.i-toolbox { .i-toolbox {
...@@ -356,6 +309,7 @@ ...@@ -356,6 +309,7 @@
cursor: pointer; cursor: pointer;
text-align: left; text-align: left;
display: flex; display: flex;
@include k-no-select();
} }
.i-active { .i-active {
background-color: antiquewhite; background-color: antiquewhite;
......
@import '../../style/common_mixin.css'; @import '../../style/common_mixin';
.cmp-player-content-wrapper{ .cmp-player-content-wrapper{
max-height: 100%; max-height: 100%;
......
...@@ -5,21 +5,16 @@ ...@@ -5,21 +5,16 @@
[nzAction]="uploadUrl" [nzAction]="uploadUrl"
[nzData]="uploadData" [nzData]="uploadData"
(nzChange)="handleChange($event)"> (nzChange)="handleChange($event)">
<!--[nzBeforeUpload]="customUpload">-->
<div class="p-box d-flex align-items-center"> <div class="p-box d-flex align-items-center">
<div class="p-upload-icon" *ngIf="!picUrl && !uploading"> <div class="p-upload-icon" *ngIf="!picUrl && !uploading">
<i nz-icon nzType="cloud-upload" nzTheme="outline" [style.font-size]="iconSize + 'em'"></i> <i nz-icon type="cloud-upload" theme="outline" [style.font-size]="iconSize + 'em'"></i>
<div class="m-3"></div> <div class="m-3"></div>
<span>{{TIP}}</span> <span>{{TIP}}</span>
<!--<div class="mt-5 p-progress-bar" *ngIf="uploading">-->
<!--<div class="p-progress-bg" [style.width]="progress*0.2+'rem'"></div>-->
<!--<div class="p-progress-value">{{progress}}%</div>-->
<!--</div>-->
</div> </div>
<div class="p-upload-progress-bg" *ngIf="uploading"> <div class="p-upload-progress-bg" *ngIf="uploading">
<div class="i-bg" [style.width]="progress+'%'"></div> <div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text"> <div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon> <fa-icon name="cloud-upload"></fa-icon>
Uploading... Uploading...
</div> </div>
</div> </div>
...@@ -32,6 +27,6 @@ ...@@ -32,6 +27,6 @@
nz-popconfirm nzTitle="Are you sure ?" nz-popconfirm nzTitle="Are you sure ?"
(nzOnConfirm)="onDelete()" (nzOnConfirm)="onDelete()"
> >
<i nz-icon nzType="close" nzTheme="outline"></i> <i nz-icon type="close" theme="outline"></i>
</div> </div>
</div> </div>
@import '../../style/common_mixin.css'; @import '../../style/common_mixin';
.p-image-uploader { .p-image-uploader {
position: relative; position: relative;
...@@ -52,15 +52,10 @@ ...@@ -52,15 +52,10 @@
.p-preview { .p-preview {
width: 100%; width: 100%;
height: 100%; height: 100%;
background-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
//background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"); //background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
@include k-img-bg();
} }
} }
.d-flex{
display: flex;
}
} }
.p-btn-delete { .p-btn-delete {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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