Browse Source

工作联系人教材资源文件管理

warrior 1 month ago
parent
commit
5c01df59f7

+ 3 - 1
projects/textbook/src/modules/nav-admin/components/collect-textbook/collect-textbook.component.ts

@@ -106,6 +106,8 @@ export class CollectTextbookComponent implements OnInit {
           $or: [
             {
               title: { $regex: `.*${val || ''}.*` },
+            },
+            {
               code: { $regex: `.*${val || ''}.*` },
             },
             {
@@ -192,7 +194,7 @@ export class CollectTextbookComponent implements OnInit {
     console.log(this.limit);
     // this.onAllChecked(false)
     this.pageIndex = 1;
-    this.getTextbook();
+    this.getTextbook(this.searchValue);
   }
 
   toUrl(url: string, param?: Object) {

+ 59 - 22
projects/textbook/src/modules/nav-province-contact/collect-file/collect-file.component.html

@@ -39,7 +39,7 @@
     [nzPageSizeOptions]="[10, 20, 30, 40, 50]"
     nzShowSizeChanger
     (nzPageIndexChange)="pageIndexChange($event)"
-    (nzPageSizeChange)="onPageSizeChange($event)"
+    (nzPageSizeChange)="onPageSizeChange()"
   >
     <thead>
       <tr>
@@ -100,9 +100,17 @@
               ?.get("name")
           }}
         </td>
-        <td nzEllipsis nzAlign="center">未上传</td>
+        <td nzEllipsis nzAlign="center">
+          <span [style.color]="statusMap[data.id].color">{{
+            statusMap[data.id].status
+          }}</span>
+        </td>
         <td nzEllipsis nzRight nzAlign="center">
-          <a nz-button nzType="link" (click)="onEditModal(data)">上传</a>
+          @if (statusMap[data.id].btn) {
+          <a nz-button nzType="link" (click)="onEditModal(data)">{{
+            statusMap[data.id].btn
+          }}</a>
+          }@else { - }
         </td>
       </tr>
       }
@@ -118,7 +126,6 @@
   </div>
 </div>
 
-
 <nz-modal
   [(nzVisible)]="isVisible"
   nzTitle="上传教材源文件"
@@ -126,29 +133,59 @@
   nzWidth="600px"
 >
   <ng-container *nzModalContent>
-    <div nz-row class="depart-modal">
-      <div nz-col nzSpan="24">
-        <div class="row">
-         <div class="title-name">纸质教材PDF文件</div>
-         <div class="desc">单个文件不超过500MB</div>
-        </div>
-        <div class="row">
-          <div class="title-name">数字教材</div>
-          <div class="desc">可单选上次文件、链接、链接和账号密码三种格式,上传文件总大小不可超过500MB</div>
-          <div class="value">
-          </div>
-        </div>
-        <div class="row" style="align-items: start;">
-          <div class="label">收集教材</div>
-          <div class="value">
+    <div nz-row class="modal-content">
+      @if (currentTextbook?.get('type')=='全册') {
+      <nz-collapse [nzBordered]="false">
+        @for (panel of currentTextbook?.get('childrens'); track panel) { @if
+        (panel?.get('editionUnit') == this.eduProcess?.get('name')) {
+        <nz-collapse-panel
+          #p
+          [nzHeader]="title"
+          [nzActive]="false"
+          nzExpandedIcon="caret-right"
+          style="
+            background: #f7f7f7;
+            border-radius: 4px;
+            margin-bottom: 24px;
+            border: 0px;
+          "
+        >
+          <ng-template #title>
+            <span class="panel-title">{{
+              "分册" + ($index + 1) + "-" + currentTextbook?.get("title")
+            }}</span>
+          </ng-template>
+          <div class="">
+            <app-upload-collect
+              #children
+              [eduTextbookVolume]="panel"
+            ></app-upload-collect>
           </div>
-        </div>
-      </div>
+          <ng-template #expandedIcon let-active>
+            {{ active }}
+            <span
+              nz-icon
+              nzType="caret-right"
+              class="ant-collapse-arrow"
+              [nzRotate]="p.nzActive ? 90 : -90"
+            ></span>
+          </ng-template>
+        </nz-collapse-panel>
+        } }
+      </nz-collapse>
+      } @else {
+      <app-upload-collect
+        #children
+        [eduTextbookVolume]="currentTextbook?.get('childrens')[0]"
+      ></app-upload-collect>
+      }
     </div>
   </ng-container>
   <div *nzModalFooter>
     <button nz-button nzType="default" (click)="handleCancel()">取消</button>
-    <button nz-button nzType="default" (click)="saveCollect('sbmit')">提交</button>
+    <button nz-button nzType="default" (click)="saveCollect('sbmit')">
+      提交
+    </button>
     <button
       nz-button
       nzType="primary"

+ 16 - 12
projects/textbook/src/modules/nav-province-contact/collect-file/collect-file.component.scss

@@ -52,16 +52,20 @@
 ::ng-deep .nz-table-hide-scrollbar {
   scrollbar-color: auto;
 }
-.row {
-  width: 100%;
-  margin-bottom: 20px;
-  // display: flex;
-  // align-items: center;
-  .label {
-    width: 100px;
-  }
-  .desc{
-    color: rgba(0, 0, 0, 0.4509803922);
-    font-size: 14px;
-  }
+// .row {
+//   width: 100%;
+//   margin-bottom: 20px;
+//   // display: flex;
+//   // align-items: center;
+//   .label {
+//     width: 100px;
+//   }
+//   .desc{
+//     color: rgba(0, 0, 0, 0.4509803922);
+//     font-size: 14px;
+//   }
+// }
+.modal-content{
+  max-height: 500px;
+  overflow-y: scroll;
 }

+ 87 - 37
projects/textbook/src/modules/nav-province-contact/collect-file/collect-file.component.ts

@@ -1,4 +1,10 @@
-import { Component, Input, OnInit } from '@angular/core';
+import {
+  Component,
+  Input,
+  OnInit,
+  QueryList,
+  ViewChildren,
+} from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { NzSpaceModule } from 'ng-zorro-antd/space';
 import { CommonCompModule } from '../../../services/common.modules';
@@ -12,6 +18,9 @@ import { MatDialog } from '@angular/material/dialog';
 import { NzEmptyModule } from 'ng-zorro-antd/empty';
 import { DatePipe } from '@angular/common';
 import { NzPopoverModule } from 'ng-zorro-antd/popover';
+import { UploadCollectComponent } from '../components/upload-collect/upload-collect.component';
+import { NzCollapseModule } from 'ng-zorro-antd/collapse';
+
 @Component({
   selector: 'app-collect-file',
   templateUrl: './collect-file.component.html',
@@ -23,6 +32,8 @@ import { NzPopoverModule } from 'ng-zorro-antd/popover';
     NzMessageModule,
     NzEmptyModule,
     NzPopoverModule,
+    UploadCollectComponent,
+    NzCollapseModule,
   ],
   providers: [DatePipe],
   standalone: true,
@@ -32,10 +43,13 @@ export class CollectFileComponent implements OnInit {
   eduProcess?: Parse.Object; //流程
   count: number = 0;
 
-  @Input('limit') limit: number = 10;
+  limit: number = 10;
   pageIndex: number = 1;
   loading: boolean = false;
   @Input('maxWidth') maxWidth: any; //最大宽度
+  @ViewChildren(UploadCollectComponent) children:
+    | QueryList<UploadCollectComponent>
+    | any;
 
   searchValue: string = '';
   time: any;
@@ -65,6 +79,8 @@ export class CollectFileComponent implements OnInit {
   isVisible: boolean = false;
   currentTextbook?: Parse.Object; //当前编辑教材
 
+  statusMap: any = {}; //任务状态
+
   constructor(
     private msg: NzMessageService,
     public tbookSer: textbookServer,
@@ -88,7 +104,7 @@ export class CollectFileComponent implements OnInit {
     this.eduProcess = r;
   }
 
-  async getTextbook(val?: string, review?: boolean): Promise<any[] | void> {
+  async getTextbook(val?: string): Promise<any[] | void> {
     if (this.loading) return;
     this.loading = true;
     try {
@@ -97,6 +113,8 @@ export class CollectFileComponent implements OnInit {
           $or: [
             {
               title: { $regex: `.*${val || ''}.*` },
+            },
+            {
               code: { $regex: `.*${val || ''}.*` },
             },
             {
@@ -107,9 +125,6 @@ export class CollectFileComponent implements OnInit {
                       {
                         ISBN: { $regex: `.*${val || ''}.*` },
                       },
-                      // {
-                      //   author: { $regex: `.*${val || ''}.*` },
-                      // },
                     ],
                   },
                   className: 'EduTextbookVolume',
@@ -135,8 +150,6 @@ export class CollectFileComponent implements OnInit {
       query.equalTo('status', '400');
       query.equalTo('recommend', true);
       query.notEqualTo('discard', true);
-      // query.exists('score');
-      // query.equalTo('verify', true);
       query.include(
         'childrens',
         'eduProcess.profileSubmitted.user',
@@ -145,30 +158,46 @@ export class CollectFileComponent implements OnInit {
       this.count = await query.count();
       query.limit(this.limit);
       query.skip(this.limit * (this.pageIndex - 1));
-      // if (exported) {
-      //   query.limit(1000);
-      //   let r = await query.find();
-      //   this.loading = false;
-      //   return r;
-      // }
       this.textbookList = await query.find();
       //获取对应出版单位管理员
-      // if(!review && this.textbookList.length > 0){
-      //   let contains:Array<string> = []
-      //   this.textbookList.forEach((childs:any)=>{
-      //     childs.get('childrens').forEach((item:Parse.Object)=> contains.push(item.get('editionUnit')))
-      //   })
-      //   let queryProcess = new Parse.Query('EduProcess')
-      //   queryProcess.notEqualTo('isDeleted',true)
-      //   queryProcess.containedIn('name',[...new Set(contains)])
-      //   queryProcess.include('profileSubmitted.user')
-      //   queryProcess.select('profileSubmitted.user.name','name')
-      //   let processList = await queryProcess.find()
-      //   console.log(processList);
-      //   processList.forEach(i=>{
-      //     this.manageProfiles[i?.get('name')] = i?.get('profileSubmitted')?.get('user')?.get('name')
-      //   })
-      // }
+      this.textbookList.forEach((item) => {
+        this.statusMap[item.id] = {
+          status: '待上传',
+          color: '#1890ff',
+          btn: '上传',
+        };
+        //是否保存
+        let isSave = item?.get('childrens').some((child: Parse.Object) => {
+          return (
+            this.eduProcess?.get('name') == child?.get('editionUnit') &&
+            child?.get('collectStatus') == '100'
+          );
+        });
+        if (isSave) {
+          this.statusMap[item.id] = {
+            status: '已保存',
+            color: '#20c94e',
+            btn: '编辑',
+          };
+          return;
+        }
+        //是否提交
+        let isSbmit = item?.get('childrens').every((child: Parse.Object) => {
+          return (
+            this.eduProcess?.get('name') != child?.get('editionUnit') ||
+            (this.eduProcess?.get('name') == child?.get('editionUnit') &&
+              child?.get('collectStatus') == '200')
+          );
+        });
+        console.log(isSbmit);
+        if (isSbmit) {
+          this.statusMap[item.id] = {
+            status: '已提交',
+            color: '#7a7a7a',
+            btn: false,
+          };
+        }
+      });
       console.log(this.textbookList);
       this.loading = false;
     } catch (err) {
@@ -192,11 +221,10 @@ export class CollectFileComponent implements OnInit {
     this.getTextbook(this.searchValue);
   }
   //切换分页条数
-  onPageSizeChange($event: any): void {
+  onPageSizeChange(): void {
     console.log(this.limit);
-    // this.onAllChecked(false)
     this.pageIndex = 1;
-    this.getTextbook();
+    this.getTextbook(this.searchValue);
   }
 
   toUrl(url: string, param?: Object) {
@@ -208,15 +236,37 @@ export class CollectFileComponent implements OnInit {
     this.route.navigate([url]);
   }
   //打开上传弹窗
-  onEditModal(data:Parse.Object){
-    this.currentTextbook = data
-    this.isVisible = true
+  onEditModal(data: Parse.Object) {
+    this.currentTextbook = data;
+    this.isVisible = true;
   }
   handleCancel(): void {
     this.isVisible = false;
     this.currentTextbook = undefined;
   }
-  saveCollect(type:string) {
+  async saveCollect(type: string): Promise<any> {
     console.log(type);
+    let isVrifly = await this.saveEduTextbookVolume(type);
+    if (!isVrifly) return this.msg.warning('已保存,填写信息不完整');
+    this.msg.success(type == 'save' ? '保存成功' : '提交成功');
+    this.isVisible = false;
+    this.getTextbook();
+  }
+
+  /**上传分册数据 */
+  async saveEduTextbookVolume(type: string): Promise<any> {
+    let isVrifly = true; //默认都通过,若一项填写未完成,则不通过
+    return Promise.all(
+      this.children.map(async (comp: any) => {
+        let complete = await comp.submitForm(type);
+        if (!complete) {
+          isVrifly = false;
+        }
+        return isVrifly;
+      })
+    ).then((data) => {
+      console.log(isVrifly);
+      return isVrifly;
+    });
   }
 }

+ 1 - 1
projects/textbook/src/modules/nav-province-contact/components/review-details/review-details.component.html

@@ -31,7 +31,7 @@
     [nzPageSizeOptions]="[10, 20, 30, 40, 50]"
     nzShowSizeChanger
     (nzPageIndexChange)="pageIndexChange($event)"
-    (nzPageSizeChange)="onPageSizeChange($event)"
+    (nzPageSizeChange)="onPageSizeChange()"
   >
     <thead>
       <tr>

+ 2 - 2
projects/textbook/src/modules/nav-province-contact/components/review-details/review-details.component.ts

@@ -216,11 +216,11 @@ export class ReviewDetailsComponent implements OnInit {
     this.getTextbook(this.searchValue);
   }
   //切换分页条数
-  onPageSizeChange($event: any): void {
+  onPageSizeChange(): void {
     console.log(this.limit);
     // this.onAllChecked(false)
     this.pageIndex = 1;
-    this.getTextbook();
+    this.getTextbook(this.searchValue);
   }
 
   toUrl(url: string, param?: Object) {

+ 93 - 0
projects/textbook/src/modules/nav-province-contact/components/upload-collect/upload-collect.component.html

@@ -0,0 +1,93 @@
+<div nz-row class="depart-modal">
+  <div nz-col nzSpan="24">
+    @if (eduTextbookVolume?.get('carrierShape') == '纸质教材'
+    ||eduTextbookVolume?.get('carrierShape') == '纸质教材附带电子资源') {
+    <div class="row">
+      <div class="title-name">纸质教材PDF文件</div>
+      <div class="desc">单个文件不超过500M</div>
+      <div>
+        <app-comp-upload
+          [files]="
+            eduTextbookVolume?.get('collectFiles')
+              ? eduTextbookVolume?.get('collectFiles')
+              : []
+          "
+          [type]="'pdf'"
+          [width]="500"
+          (change)="upload($event, 'collectFiles')"
+          title="上传文件"
+          [size]="512000"
+          [maxlenght]="10"
+        ></app-comp-upload>
+      </div>
+    </div>
+    } @if (eduTextbookVolume?.get('carrierShape') == '数字教材'
+    ||eduTextbookVolume?.get('carrierShape') == '纸质教材附带电子资源') {
+    <div class="row">
+      <div class="title-name">数字教材</div>
+      <div class="desc">
+        可单选上次文件、链接、链接和账号密码三种格式,上传文件总大小不可超过500M
+      </div>
+      <div class="value">
+        <nz-radio-group [(ngModel)]="radioValue">
+          <label nz-radio nzValue="上传文件">上传文件</label>
+          <label nz-radio nzValue="链接">链接</label>
+          <label nz-radio nzValue="链接和账号密码">链接和账号密码</label>
+        </nz-radio-group>
+      </div>
+      @if (radioValue == '链接') {
+      <div class="desc">请填写可以直接访问数字教材的链接</div>
+      <input
+        style="margin-bottom: 10px"
+        nz-input
+        placeholder="请填写可以直接访问数字教材的链接"
+        [(ngModel)]="collectLink.url"
+        type="text"
+      />
+      }@else if (radioValue == '链接和账号密码') {
+      <div class="desc">请填写可以访问数字教材的链接</div>
+      <input
+        style="margin-bottom: 10px"
+        nz-input
+        placeholder="请填写可以访问数字教材的链接"
+        [(ngModel)]="collectLink.url"
+        type="text"
+      />
+      <div class="desc">请填写可以访问数字教材的账号</div>
+      <input
+        style="margin-bottom: 10px"
+        nz-input
+        placeholder="请填写可以访问数字教材的账号"
+        [(ngModel)]="collectLink.username"
+        type="text"
+      />
+      <div class="desc">请填写可以访问数字教材的密码</div>
+      <input
+        style="margin-bottom: 10px"
+        nz-input
+        placeholder="请填写可以访问数字教材的密码"
+        [(ngModel)]="collectLink.password"
+        type="text"
+      />
+      } @else {
+      <div class="desc">批量上传数字文件,支持PDF格式,总大小不可超过500M</div>
+      <div>
+        <app-comp-upload
+          [files]="
+            eduTextbookVolume?.get('collectFiles')
+              ? eduTextbookVolume?.get('collectFiles')
+              : []
+          "
+          [type]="'pdf'"
+          [width]="500"
+          (change)="upload($event, 'collectDigitFiles')"
+          title="上传文件"
+          [size]="512000"
+          [maxlenght]="10"
+        ></app-comp-upload>
+      </div>
+      }
+    </div>
+    }
+  </div>
+</div>

+ 14 - 0
projects/textbook/src/modules/nav-province-contact/components/upload-collect/upload-collect.component.scss

@@ -0,0 +1,14 @@
+.row {
+  width: 100%;
+  margin-bottom: 20px;
+  // display: flex;
+  // align-items: center;
+  .label {
+    width: 100px;
+  }
+  .desc{
+    color: rgba(0, 0, 0, 0.4509803922);
+    font-size: 14px;
+    margin-bottom: 10px;
+  }
+}

+ 24 - 0
projects/textbook/src/modules/nav-province-contact/components/upload-collect/upload-collect.component.spec.ts

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

+ 95 - 0
projects/textbook/src/modules/nav-province-contact/components/upload-collect/upload-collect.component.ts

@@ -0,0 +1,95 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import Parse from 'parse';
+import { CompUploadComponent } from '../../../../app/comp-upload/comp-upload.component';
+import { NzRadioModule } from 'ng-zorro-antd/radio';
+import { CommonCompModule } from '../../../../services/common.modules';
+import { NzMessageService } from 'ng-zorro-antd/message';
+interface link {
+  url: string;
+  username?: string;
+  password?: string;
+}
+@Component({
+  selector: 'app-upload-collect',
+  templateUrl: './upload-collect.component.html',
+  styleUrls: ['./upload-collect.component.scss'],
+  standalone: true,
+  imports: [CommonCompModule, CommonModule, CompUploadComponent, NzRadioModule],
+})
+export class UploadCollectComponent implements OnInit {
+  @Input('eduTextbookVolume') eduTextbookVolume: Parse.Object | undefined;
+  @Output() save: EventEmitter<any> = new EventEmitter<any>();
+
+  collectFiles: Array<any> = []; //纸质教材PDF文件列表
+  collectDigitFiles: Array<any> = []; //数字资源PDF文件列表
+  collectLink: link = {
+    url: '',
+    username: '',
+    password: '',
+  }; //链接、账号密码
+
+  radioValue: string = '上传文件';
+
+  constructor(private msg: NzMessageService) {}
+
+  ngOnInit() {
+    this.collectFiles = this.eduTextbookVolume?.get('collectFiles');
+    this.collectDigitFiles = this.eduTextbookVolume?.get('collectDigitFiles');
+    this.collectLink = this.eduTextbookVolume?.get('collectLink');
+    this.radioValue = this.eduTextbookVolume?.get('collectCheck');
+  }
+  upload(e: any, type: string) {
+    console.log('上传材料发生改变');
+    console.log(e);
+    if (type == 'collectFiles' || type == 'collectDigitFiles') {
+      this[type] = e;
+    }
+  }
+  async submitForm(type: string) {
+    if (
+      this.eduTextbookVolume?.get('carrierShape') == '纸质教材' ||
+      this.eduTextbookVolume?.get('carrierShape') == '纸质教材附带电子资源'
+    ) {
+      let upload = this.collectFiles?.some((item) => item.url);
+      console.log(upload);
+      if (!upload && type == 'sbmit') {
+        // this.msg.warning('请上传纸质教材PDF文件');
+        return;
+      }
+      this.eduTextbookVolume?.set('collectFiles', this.collectFiles);
+    }
+    if (
+      this.eduTextbookVolume?.get('carrierShape') == '数字教材' ||
+      this.eduTextbookVolume?.get('carrierShape') == '纸质教材附带电子资源'
+    ) {
+      let upload = this.collectDigitFiles?.some((item) => item.url);
+      console.log(upload);
+      if (this.radioValue == '上传文件' && !upload && type == 'sbmit') {
+        // this.msg.warning('请上传数字文件PDF');
+        return;
+      }
+      this.eduTextbookVolume?.set('collectDigitFiles', this.collectDigitFiles);
+      this.eduTextbookVolume?.set('collectCheck', this.radioValue);
+      if (
+        type == 'sbmit' &&
+        ((this.radioValue == '链接' && !this.collectLink?.url) ||
+          (this.radioValue == '链接和账号密码' &&
+            (!this.collectLink?.url ||
+              !this.collectLink?.username ||
+              !this.collectLink?.password)))
+      ) {
+        // this.msg.warning('请填写完整信息');
+        return;
+      }
+      this.eduTextbookVolume?.set('collectLink', this.collectLink);
+    }
+    /* 100:已上传 200:已提交*/
+    this.eduTextbookVolume?.set(
+      'collectStatus',
+      type == 'sbmit' ? '200' : '100'
+    );
+    await this.eduTextbookVolume?.save();
+    return true;
+  }
+}