2 次代碼提交 2ef0e73bd5 ... 66609bffb6

作者 SHA1 備註 提交日期
  warrior 66609bffb6 Merge branch 'master' of http://git.fmode.cn:3000/bin/edu-textbook 1 周之前
  warrior 648269d2ed 收集教材源文件总管理员端&工作联系人端 1 周之前

+ 71 - 2
projects/textbook/src/modules/nav-admin/components/collect-textbook/collect-textbook.component.html

@@ -109,9 +109,17 @@
             </div>
           </ng-template>
         </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">查看</a>
+          @if (statusMap[data.id].btn == '查看') {
+          <a nz-button nzType="link" (click)="onReview(data)"> 查看</a>
+          }@else {
+          <a nz-button nzType="link" (click)="onEmitMsg(data)">提醒</a>
+          }
         </td>
       </tr>
       }
@@ -266,3 +274,64 @@
     </button>
   </div>
 </nz-modal>
+
+<nz-modal
+  [(nzVisible)]="isVisible"
+  nzTitle="上传教材源文件"
+  (nzOnCancel)="isVisible = false"
+  nzWidth="600px"
+>
+  <ng-container *nzModalContent>
+    <div nz-row class="modal-content">
+      @if (currentTextbook?.get('type')=='全册') {
+      <nz-collapse [nzBordered]="false">
+        @for (panel of currentTextbook?.get('childrens'); track panel) {
+        <nz-collapse-panel
+          #p
+          [nzHeader]="title"
+          [nzActive]="true"
+          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"
+              [review]="true"
+            ></app-upload-collect>
+          </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
+        [review]="true"
+        [eduTextbookVolume]="currentTextbook?.get('childrens')[0]"
+      ></app-upload-collect>
+      }
+    </div>
+  </ng-container>
+  <div *nzModalFooter>
+    <button nz-button nzType="primary" (click)="isVisible = false">关闭</button>
+  </div>
+</nz-modal>

+ 4 - 0
projects/textbook/src/modules/nav-admin/components/collect-textbook/collect-textbook.component.scss

@@ -99,4 +99,8 @@
   .label{
     width: 100px;
   }
+}
+.modal-content{
+  max-height: 500px;
+  overflow-y: scroll;
 }

+ 78 - 32
projects/textbook/src/modules/nav-admin/components/collect-textbook/collect-textbook.component.ts

@@ -14,6 +14,8 @@ import { DatePipe } from '@angular/common';
 import { NzPopoverModule } from 'ng-zorro-antd/popover';
 import { setHours } from 'date-fns';
 import { NzDatePickerModule } from 'ng-zorro-antd/date-picker';
+import { UploadCollectComponent } from '../../../nav-province-contact/components/upload-collect/upload-collect.component';
+import { NzCollapseModule } from 'ng-zorro-antd/collapse';
 @Component({
   selector: 'app-collect-textbook',
   templateUrl: './collect-textbook.component.html',
@@ -25,7 +27,9 @@ import { NzDatePickerModule } from 'ng-zorro-antd/date-picker';
     NzMessageModule,
     NzEmptyModule,
     NzPopoverModule,
-    NzDatePickerModule
+    NzDatePickerModule,
+    UploadCollectComponent,
+    NzCollapseModule
   ],
   providers: [DatePipe],
   standalone: true,
@@ -74,15 +78,19 @@ export class CollectTextbookComponent implements OnInit {
     }
     return j || '-';
   }
-  manageProfiles:any = {}
+  manageProfiles: any = {};
 
-  formatMapProfile(list:Array<Parse.Object>):Array<string>{
-    let arr:Array<string> = []
-    list.forEach(item=>{
-      arr.push(this.manageProfiles[item?.get('editionUnit')]) 
-    })
-    return [...new Set(arr)]
+  formatMapProfile(list: Array<Parse.Object>): Array<string> {
+    let arr: Array<string> = [];
+    list.forEach((item) => {
+      arr.push(this.manageProfiles[item?.get('editionUnit')]);
+    });
+    return [...new Set(arr)];
   }
+  statusMap: any = {}; //任务状态
+
+  isVisible: boolean = false;
+  currentTextbook?: Parse.Object; //当前预览教材
 
   constructor(
     // private activeRoute: ActivatedRoute,
@@ -137,35 +145,64 @@ export class CollectTextbookComponent implements OnInit {
       query.equalTo('status', '400');
       query.equalTo('recommend', true);
       query.notEqualTo('discard', true);
-      // query.exists('score');
-      // query.equalTo('verify', true);
       query.include('childrens');
       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()
+      if (!review && this.textbookList.length > 0) {
+        let contains: Array<string> = [];
+        this.textbookList.forEach((item: any) => {
+          item
+            .get('childrens')
+            .forEach((child: Parse.Object) =>
+              contains.push(child.get('editionUnit'))
+            );
+
+          this.statusMap[item.id] = {
+            status: '待上传',
+            color: '#1890ff',
+            btn: '提醒',
+          };
+          //是否保存
+          // let isSave = item?.get('childrens').some((child: Parse.Object) => {
+          //   return child?.get('collectStatus') == '100';
+          // });
+          // if (isSave) {
+          //   this.statusMap[item.id] = {
+          //     status: '待上传',
+          //     color: '#1890ff',
+          //     btn: '提醒',
+          //   };
+          //   return;
+          // }
+          //是否提交
+          let isSbmit = item?.get('childrens').every((child: Parse.Object) => {
+            return child?.get('collectStatus') == '200';
+          });
+          console.log(isSbmit);
+          if (isSbmit) {
+            this.statusMap[item.id] = {
+              status: '已提交',
+              color: '#20c94e',
+              btn: '查看',
+            };
+          }
+        });
+        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')
-        })
+        processList.forEach((i) => {
+          this.manageProfiles[i?.get('name')] = i
+            ?.get('profileSubmitted')
+            ?.get('user')
+            ?.get('name');
+        });
       }
       console.log(this.textbookList);
       this.loading = false;
@@ -206,18 +243,27 @@ export class CollectTextbookComponent implements OnInit {
     this.route.navigate([url]);
   }
 
+  onReview(data:Parse.Object){
+    this.currentTextbook = data;
+    this.isVisible = true;
+  }
+  //短信提醒
+  onEmitMsg(data:Parse.Object){
+    console.log(data);
+  }
+
   //打开编辑收集文件弹窗
   async openEditCollect() {
     this.collectStartData = this.eduProcess?.get('collectStartData');
     this.collectEndData = this.eduProcess?.get('collectEndData');
     this.pageIndex = 1;
-    this.searchValue = ''
+    this.searchValue = '';
     this.getTextbook();
 
     this.showModal = true;
   }
   handleCancel(): void {
-    this.showModal = false
+    this.showModal = false;
   }
   //保存收集文件设置
   async editCollect() {

+ 4 - 3
projects/textbook/src/modules/nav-province-contact/collect-file/collect-file.component.html

@@ -137,7 +137,7 @@
       @if (currentTextbook?.get('type')=='全册') {
       <nz-collapse [nzBordered]="false">
         @for (panel of currentTextbook?.get('childrens'); track panel) { @if
-        (panel?.get('editionUnit') == this.eduProcess?.get('name')) {
+          (panel?.get('editionUnit') == this.eduProcess?.get('name')) {
         <nz-collapse-panel
           #p
           [nzHeader]="title"
@@ -182,8 +182,8 @@
     </div>
   </ng-container>
   <div *nzModalFooter>
-    <button nz-button nzType="default" (click)="handleCancel()">取消</button>
-    <button nz-button nzType="default" (click)="saveCollect('sbmit')">
+    <button nz-button nzType="default" [disabled]="btnLoading" (click)="handleCancel()">取消</button>
+    <button nz-button nzType="default" [nzLoading]="btnLoading" (click)="saveCollect('sbmit')">
       提交
     </button>
     <button
@@ -191,6 +191,7 @@
       nzType="primary"
       [disabled]="false"
       (click)="saveCollect('save')"
+      [nzLoading]="btnLoading"
     >
       保存
     </button>

+ 20 - 4
projects/textbook/src/modules/nav-province-contact/collect-file/collect-file.component.ts

@@ -136,7 +136,7 @@ export class CollectFileComponent implements OnInit {
             $inQuery: {
               where: {
                 editionUnit: this.eduProcess?.get('name'),
-                // editionUnit: '山东大学出版社',
+                // editionUnit: '高等教育出版社',
               },
               className: 'EduTextbookVolume',
             },
@@ -144,7 +144,6 @@ export class CollectFileComponent implements OnInit {
         },
       };
       let query = Parse.Query.fromJSON('EduTextbook', queryParams);
-      // query.equalTo('eduProcess', this.eduProcess?.id);
       query.descending('updatedAt');
       query.notEqualTo('isDeleted', true);
       query.equalTo('status', '400');
@@ -237,6 +236,15 @@ export class CollectFileComponent implements OnInit {
   }
   //打开上传弹窗
   onEditModal(data: Parse.Object) {
+    if (
+      !this.eduProcess?.get('collectStartData') ||
+      !this.eduProcess?.get('collectEndData') ||
+      this.eduProcess?.get('collectStartData') > new Date() ||
+      this.eduProcess?.get('collectEndData') < new Date()
+    ) {
+      this.msg.warning('非收集文件工作期内');
+      return;
+    }
     this.currentTextbook = data;
     this.isVisible = true;
   }
@@ -244,13 +252,20 @@ export class CollectFileComponent implements OnInit {
     this.isVisible = false;
     this.currentTextbook = undefined;
   }
+  btnLoading: boolean = false;
   async saveCollect(type: string): Promise<any> {
     console.log(type);
+    this.btnLoading = true;
     let isVrifly = await this.saveEduTextbookVolume(type);
-    if (!isVrifly) return this.msg.warning('已保存,填写信息不完整');
+    if (!isVrifly) {
+      this.btnLoading = false;
+      this.msg.warning('已保存,填写信息不完整');
+      return;
+    }
     this.msg.success(type == 'save' ? '保存成功' : '提交成功');
+    this.btnLoading = false;
     this.isVisible = false;
-    this.getTextbook();
+    this.getTextbook(this.searchValue);
   }
 
   /**上传分册数据 */
@@ -259,6 +274,7 @@ export class CollectFileComponent implements OnInit {
     return Promise.all(
       this.children.map(async (comp: any) => {
         let complete = await comp.submitForm(type);
+        console.log(comp?.eduTextbookVolume?.id + '===' + complete);
         if (!complete) {
           isVrifly = false;
         }

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

@@ -1,3 +1,58 @@
+@if (review) {
+<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>
+        @for (item of eduTextbookVolume?.get('collectFiles'); track $index) {
+        <a (click)="openUrl(item.url)">{{ item.name }}</a>
+        }
+      </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>
+      <a style="margin-bottom: 10px" (click)="openUrl(collectLink.url)">
+        {{ collectLink.url }}
+      </a>
+      }@else if (radioValue == '链接和账号密码') {
+      <div class="desc">数字教材链接</div>
+      <a style="margin-bottom: 10px" (click)="openUrl(collectLink.url)">
+        {{ collectLink.url }}
+      </a>
+      <div class="desc">数字教材账号</div>
+      <p style="margin-bottom: 10px">{{ collectLink.username }}</p>
+      <div class="desc">数字教材密码</div>
+      <p style="margin-bottom: 10px">{{ collectLink.password }}</p>
+      } @else {
+      <div class="desc">数字教材文件</div>
+      <div>
+        @for (item of eduTextbookVolume?.get('collectDigitFiles'); track $index)
+        {
+        <a (click)="openUrl(item.url)">{{ item.name }}</a>
+        }
+      </div>
+      }
+    </div>
+    }
+  </div>
+</div>
+}@else {
 <div nz-row class="depart-modal">
   <div nz-col nzSpan="24">
     @if (eduTextbookVolume?.get('carrierShape') == '纸质教材'
@@ -74,8 +129,8 @@
       <div>
         <app-comp-upload
           [files]="
-            eduTextbookVolume?.get('collectFiles')
-              ? eduTextbookVolume?.get('collectFiles')
+            eduTextbookVolume?.get('collectDigitFiles')
+              ? eduTextbookVolume?.get('collectDigitFiles')
               : []
           "
           [type]="'pdf'"
@@ -91,3 +146,4 @@
     }
   </div>
 </div>
+}

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

@@ -12,3 +12,6 @@
     margin-bottom: 10px;
   }
 }
+::ng-deep .ant-collapse-borderless{
+  width: 100%;
+}

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

@@ -18,6 +18,7 @@ interface link {
   imports: [CommonCompModule, CommonModule, CompUploadComponent, NzRadioModule],
 })
 export class UploadCollectComponent implements OnInit {
+  @Input('review') review: boolean = false; //只读
   @Input('eduTextbookVolume') eduTextbookVolume: Parse.Object | undefined;
   @Output() save: EventEmitter<any> = new EventEmitter<any>();
 
@@ -52,7 +53,7 @@ export class UploadCollectComponent implements OnInit {
       this.eduTextbookVolume?.get('carrierShape') == '纸质教材附带电子资源'
     ) {
       let upload = this.collectFiles?.some((item) => item.url);
-      console.log(upload);
+      // console.log(upload);
       if (!upload && type == 'sbmit') {
         // this.msg.warning('请上传纸质教材PDF文件');
         return;
@@ -64,7 +65,7 @@ export class UploadCollectComponent implements OnInit {
       this.eduTextbookVolume?.get('carrierShape') == '纸质教材附带电子资源'
     ) {
       let upload = this.collectDigitFiles?.some((item) => item.url);
-      console.log(upload);
+      // console.log(upload);
       if (this.radioValue == '上传文件' && !upload && type == 'sbmit') {
         // this.msg.warning('请上传数字文件PDF');
         return;
@@ -92,4 +93,8 @@ export class UploadCollectComponent implements OnInit {
     await this.eduTextbookVolume?.save();
     return true;
   }
+
+  openUrl(url: string) {
+    window.open(url);
+  }
 }