Browse Source

Merge branch 'master' of http://git.fmode.cn:3000/bin/edu-textbook

xll 7 months ago
parent
commit
a26f763117

+ 3 - 0
projects/textbook/src/modules/nav-author/components/create/author-file/author-file.component.html

@@ -0,0 +1,3 @@
+<p>
+  author-file works!
+</p>

+ 0 - 0
projects/textbook/src/modules/nav-author/components/create/author-file/author-file.component.scss


+ 24 - 0
projects/textbook/src/modules/nav-author/components/create/author-file/author-file.component.spec.ts

@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { AuthorFileComponent } from './author-file.component';
+
+describe('AuthorFileComponent', () => {
+  let component: AuthorFileComponent;
+  let fixture: ComponentFixture<AuthorFileComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [ AuthorFileComponent ],
+      imports: [IonicModule.forRoot()]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(AuthorFileComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 14 - 0
projects/textbook/src/modules/nav-author/components/create/author-file/author-file.component.ts

@@ -0,0 +1,14 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-author-file',
+  templateUrl: './author-file.component.html',
+  styleUrls: ['./author-file.component.scss'],
+})
+export class AuthorFileComponent  implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {}
+
+}

+ 269 - 0
projects/textbook/src/modules/nav-author/components/create/author/author.component.html

@@ -0,0 +1,269 @@
+<div class="page-comp">
+  <form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
+
+  <div class="author-content">
+    <div class="nav"><span style="color: #ff4d4f;">*</span> 作者(含主编,不超过 6 人,教材中明确出现姓名)</div>
+    <!-- <nz-form-label
+      class="title"
+      [nzNoColon]="true"
+      [nzSm]="24"
+      [nzXs]="24"
+    >
+      <span style="font-size: 16px;font-family: 500;">
+        作者(含主编,不超过 6 人,教材中明确出现姓名)
+      </span>
+    </nz-form-label> -->
+    <nz-table
+      #basicTable
+      [nzData]="authorList"
+      [nzScroll]="{ x: (maxWidth || '1200') + 'px' }"
+    >
+      <thead>
+        <tr>
+          <th nzWidth="80px" nzLeft nzAlign="right">序号</th>
+          <th nzWidth="160px" nzLeft>姓名</th>
+          <th nzWidth="160px">单位</th>
+          <th nzWidth="160px">出生年月</th>
+          <th nzWidth="160px">国籍</th>
+          <th nzWidth="160px">职务</th>
+          <th nzWidth="160px">职称</th>
+          <th nzWidth="300px">手机号码</th>
+          <th nzWidth="160px">电子邮箱</th>
+          <th nzWidth="160px">分工</th>
+          <th nzWidth="100px" nzRight>操作</th>
+        </tr>
+      </thead>
+      <tbody>
+        @for (data of authorList; track data.mobile;let index = $index) {
+        <tr>
+          <td nzLeft nzAlign="right">{{ index + 1 }}</td>
+          <td nzLeft>
+            <input
+              nz-input
+              placeholder="请输入作者姓名"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.name"
+              nzStatus=""
+            />
+          </td>
+          <td>
+            <input
+              nz-input
+              placeholder="请输入作者单位"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.unit"
+              nzStatus=""
+            />
+          </td>
+          <td>
+            <nz-date-picker
+              nzMode="month"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.birth"
+            ></nz-date-picker>
+          </td>
+          <td>
+            <input
+              nz-input
+              placeholder="请输入作者国籍"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.nationality"
+              nzStatus=""
+            />
+          </td>
+          <td>
+            <input
+              nz-input
+              placeholder="请输入作者职务"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.job"
+              nzStatus=""
+            />
+          </td>
+          <td>
+            <input
+              nz-input
+              placeholder="请输入作者职称"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.title"
+              nzStatus=""
+            />
+          </td>
+          <td>
+            <nz-input-group nzCompact>
+              <nz-select
+                style="width: 90px"
+                [ngModelOptions]="{ standalone: true }"
+                [ngModel]="'+86'"
+              >
+                <nz-option [nzLabel]="'+0000'" [nzValue]="'+0000'"></nz-option>
+                <nz-option [nzLabel]="'+86'" [nzValue]="'+86'"></nz-option>
+              </nz-select>
+              <input
+                type="number"
+                nz-input
+                placeholder="请输入作者手机号码"
+                [ngModelOptions]="{ standalone: true }"
+                [(ngModel)]="data.mobile"
+                nzStatus=""
+                style="width: 160px"
+              />
+            </nz-input-group>
+          </td>
+          <td>
+            <input
+              nz-input
+              placeholder="请输入作者邮箱"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.email"
+              nzStatus=""
+            />
+          </td>
+          <td>
+            <nz-select
+              style="width: 80%"
+              nzShowSearch
+              nzAllowClear
+              nzPlaceHolder="请选择分工"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.work"
+            >
+              @for(work of workOptions; track work){
+              <nz-option nzCustomContent [nzValue]="work" [nzLabel]="work">{{
+                work
+              }}</nz-option>
+              }
+            </nz-select>
+          </td>
+          <td nzRight>
+            <a (click)="onPush('authorList', index)"
+              ><span
+                nz-icon
+                style="font-size: 20px; margin-right: 10px"
+                nzType="plus-circle"
+                nzTheme="outline"
+              ></span
+            ></a>
+            <a (click)="onDel('authorList', index)"
+              ><span
+                nz-icon
+                style="font-size: 20px"
+                nzType="delete"
+                nzTheme="outline"
+              ></span
+            ></a>
+          </td>
+        </tr>
+        }
+      </tbody>
+    </nz-table>
+  </div>
+  <div class="author-content">
+    <div class="nav">第一主编(作者)情况</div>
+    <nz-form-item class="row" style="margin-bottom: 16px">
+      <nz-form-label
+        class="title"
+        [nzNoColon]="true"
+        [nzSm]="24"
+        [nzXs]="24"
+        nzRequired
+      >
+        <span style="font-size: 14px"> 相关教学经历 </span>
+      </nz-form-label>
+      <nz-form-control
+        class="val"
+        nzErrorTip="请输入第一主编(作者)承担学校教学任务、开展教学研究情况、教材编写情况以及取得的教学成果"
+        style="width: 100%"
+      >
+        <nz-textarea-count [nzMaxCharacterCount]="500">
+          <textarea
+            rows="4"
+            maxlength="500"
+            formControlName="authorDetails"
+            placeholder="请输入第一主编(作者)承担学校教学任务、开展教学研究情况、教材编写情况以及取得的教学成果"
+            nz-input
+          ></textarea>
+        </nz-textarea-count>
+      </nz-form-control>
+    </nz-form-item>
+  </div>
+  <div class="author-content">
+    <nz-form-label
+      class="title"
+      [nzNoColon]="true"
+      [nzSm]="24"
+      [nzXs]="24"
+      nzRequired
+    >
+      <span style="font-size: 14px">
+        相关科学研究项目、成果或论文专著(限5项)
+      </span>
+    </nz-form-label>
+    <nz-table
+      #basicTable
+      [nzData]="achievementOptions"
+      [nzScroll]="{ x: (maxWidth || '1200') + 'px' }"
+    >
+      <thead>
+        <tr>
+          <th nzWidth="50px" nzLeft nzAlign="right">序号</th>
+          <th nzWidth="150px" nzLeft>名称</th>
+          <th nzWidth="120px">来源/出版单位</th>
+          <th nzWidth="120px">时间</th>
+          <th nzWidth="80px" nzRight>操作</th>
+        </tr>
+      </thead>
+      <tbody>
+        @for (data of achievementOptions; track data.name;let index = $index) {
+        <tr>
+          <td nzLeft nzAlign="right">{{ index + 1 }}</td>
+          <td nzLeft>
+            <input
+              nz-input
+              placeholder="请输入项目/成果/论文名称"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.name"
+              nzStatus=""
+            />
+          </td>
+          <td>
+            <input
+              nz-input
+              placeholder="请输入单位名称"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.unit"
+              nzStatus=""
+            />
+          </td>
+          <td>
+            <nz-date-picker
+              nzMode="month"
+              [ngModelOptions]="{ standalone: true }"
+              [(ngModel)]="data.date"
+            ></nz-date-picker>
+          </td>
+          <td nzRight>
+            <a (click)="onPush('achievementOptions', index)"
+              ><span
+                nz-icon
+                style="font-size: 20px; margin-right: 10px"
+                nzType="plus-circle"
+                nzTheme="outline"
+              ></span
+            ></a>
+            <a (click)="onDel('achievementOptions', index)"
+              ><span
+                nz-icon
+                style="font-size: 20px"
+                nzType="delete"
+                nzTheme="outline"
+              ></span
+            ></a>
+          </td>
+        </tr>
+        }
+      </tbody>
+    </nz-table>
+  </div>
+  </form>
+</div>

+ 21 - 0
projects/textbook/src/modules/nav-author/components/create/author/author.component.scss

@@ -0,0 +1,21 @@
+.author-content{
+  a{
+    color:#756B6D;
+  }
+  .nav{
+    font-family: PingFang SC;
+    font-size: 16px;
+    font-weight: 500;
+    line-height: 22px;
+    text-align: left;
+    margin: 10px 0;
+  }
+  .title{
+    font-family: PingFang SC;
+    font-size: 16px;
+    font-weight: 500;
+    line-height: 22px;
+    text-align: left;
+    margin: 10px 0;
+  }
+}

+ 24 - 0
projects/textbook/src/modules/nav-author/components/create/author/author.component.spec.ts

@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { AuthorComponent } from './author.component';
+
+describe('AuthorComponent', () => {
+  let component: AuthorComponent;
+  let fixture: ComponentFixture<AuthorComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      declarations: [ AuthorComponent ],
+      imports: [IonicModule.forRoot()]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(AuthorComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 209 - 0
projects/textbook/src/modules/nav-author/components/create/author/author.component.ts

@@ -0,0 +1,209 @@
+import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import { CommonCompModule } from '../../../../../services/common.modules';
+import { NzSelectModule } from 'ng-zorro-antd/select';
+import { ReactiveFormsModule } from '@angular/forms';
+import { NzRadioModule } from 'ng-zorro-antd/radio';
+import { NzMessageService } from 'ng-zorro-antd/message';
+import { NzGridModule } from 'ng-zorro-antd/grid';
+import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
+import { NzTableModule } from 'ng-zorro-antd/table';
+import { NzModalService } from 'ng-zorro-antd/modal';
+import { CompUploadComponent } from '../../../../../app/comp-upload/comp-upload.component';
+import {
+  FormControl,
+  FormGroup,
+  NonNullableFormBuilder,
+  Validators,
+} from '@angular/forms';
+import Parse from 'parse';
+interface author {
+  name: string;
+  unit: string;
+  birth: Date | any;
+  nationality: string;
+  job: string;
+  title: string;
+  mobile: string;
+  email: string;
+  work: string;
+  signature?: string;
+  examine?: string;
+}
+interface achievementType {
+  name: string;
+  unit: string;
+  date: Date | any;
+}
+@Component({
+  selector: 'app-author',
+  imports: [
+    CommonCompModule,
+    ReactiveFormsModule,
+    NzSelectModule,
+    NzRadioModule,
+    NzGridModule,
+    NzCheckboxModule,
+    NzTableModule,
+    CompUploadComponent,
+  ],
+  standalone: true,
+  templateUrl: './author.component.html',
+  styleUrls: ['./author.component.scss'],
+})
+export class AuthorComponent implements OnInit {
+  @Input('eduTextbook') eduTextbook: Parse.Object | any;
+  @Input('maxWidth') maxWidth: number = 0;
+  @Input('eduTextbookVolume') eduTextbookVolume: Parse.Object | any;
+
+  validateForm: FormGroup<{
+    authorDetails: FormControl<string>; //第一主编(作者)相关教学经历
+  }> = this.fb.group({
+    authorDetails: ['', [Validators.required]],
+  });
+  //作者信息
+  authorList: Array<author> = [
+    {
+      name: '',
+      unit: '',
+      birth: new Date('December 1, 1975 00:00:00'),
+      nationality: '',
+      job: '',
+      title: '',
+      mobile: '',
+      email: '',
+      work: '',
+      // signature: '',
+      // examine: '',
+    },
+  ];
+  //相关科学研究项目、成果或论文专著(限5项)
+  achievementOptions: Array<achievementType> = [
+    {
+      name: '',
+      unit: '',
+      date: '',
+    },
+  ];
+  workOptions = ['主编', '副主编', '其他编者'];
+
+  constructor(
+    private fb: NonNullableFormBuilder,
+    private modal: NzModalService,
+    private msg: NzMessageService
+  ) {}
+
+  ngOnInit() {
+    let id = this?.eduTextbookVolume?.id;
+    if (id) {
+      this.getEduTextbookVolume(id);
+    }
+  }
+  async getEduTextbookVolume(id: string) {
+    let query = new Parse.Query('EduTextbookVolume');
+    query.equalTo('objectId', id);
+    let r = await query.first();
+    this.eduTextbookVolume = r;
+    this.validateForm.get("authorDetails")?.setValue(this.eduTextbookVolume.get('authorDetails'))
+    this.authorList =
+      this.eduTextbookVolume.get('authorList') || this.authorList;
+    this.achievementOptions =
+      this.eduTextbookVolume.get('achievementOptions') ||
+      this.achievementOptions;
+  }
+  //添加作者信息
+  onPush(type: string, idx: number) {
+    switch (type) {
+      case 'authorList':
+        if (this.authorList?.length >= 6) {
+          this.msg.warning('最多添加6条');
+          break;
+        }
+        this.authorList.splice(idx + 1, 0, {
+          name: '',
+          unit: '',
+          birth: new Date('December 1, 1975 00:00:00'),
+          nationality: '',
+          job: '',
+          title: '',
+          mobile: '',
+          email: '',
+          work: '',
+          // signature: '',
+          // examine: '',
+        });
+        break;
+      case 'achievementOptions':
+        if (this.achievementOptions.length >= 5) {
+          this.msg.warning('最多添加5条');
+          return;
+        }
+        this.achievementOptions.splice(idx + 1, 0, {
+          name: '',
+          unit: '',
+          date: '',
+        });
+        break;
+    }
+  }
+  //删除作者信息
+  onDel(type: string, idx: number) {
+    switch (type) {
+      case 'authorList':
+        if (this.authorList.length == 1) {
+          this.authorList = [
+            {
+              name: '',
+              unit: '',
+              birth: new Date('December 1, 1975 00:00:00'),
+              nationality: '',
+              job: '',
+              title: '',
+              mobile: '',
+              email: '',
+              work: '',
+              // signature: '',
+              // examine: '',
+            },
+          ];
+          return;
+        }
+        this.authorList.splice(idx, 1);
+        break;
+      case 'achievementOptions':
+        if (this.achievementOptions.length == 1) {
+          this.achievementOptions = [
+            {
+              name: '',
+              unit: '',
+              date: '',
+            },
+          ];
+          return;
+        }
+        this.achievementOptions.splice(idx, 1);
+        break;
+    }
+  }
+
+  async submitForm(event?: string): Promise<boolean> {
+    let params: any = this.validateForm.value;
+    let authorListVrifly = !this.authorList.some((item) =>
+      Object.values(item).some((val) => val == '' || val == undefined)
+    );
+    let achievementOptionsVrifly = !this.achievementOptions.some((item) =>
+      Object.values(item).some((val) => val == '' || val == undefined)
+    );
+    let isComplete =
+      this.validateForm.valid && authorListVrifly && achievementOptionsVrifly;
+    await this.saveEduTextbookVolume(params, isComplete);
+    return isComplete;
+  }
+  async saveEduTextbookVolume(params: any, isComplete: boolean) {
+    this.eduTextbookVolume?.set('user', Parse.User.current()?.toPointer());
+    this.eduTextbookVolume?.set('authorList', this.authorList);
+    this.eduTextbookVolume?.set('achievementOptions', this.achievementOptions);
+    params.authorDetails &&
+      this.eduTextbookVolume?.set('authorDetails', params.authorDetails);
+    await this.eduTextbookVolume?.save();
+  }
+}