cehn há 8 meses atrás
pai
commit
67b98961c2

+ 7 - 3
projects/textbook/src/app/textbook/textbook.component.ts

@@ -185,7 +185,7 @@ export class TextbookComponent implements OnInit {
     })
     // console.log(this.filterObj.contained);
     this.pageIndex = 1
-    this.getTextbook()
+    this.getTextbook(this.searchValue)
   }
   statusFilter:Array<string> = []
   initContained:Array<string> = []
@@ -438,10 +438,14 @@ export class TextbookComponent implements OnInit {
     this.pageIndex = 1;
     this.getTextbook(this.searchValue);
   }
+  time:any //节流
   onSearch(e: string) {
     this.pageIndex = 1;
     console.log(e);
-    this.getTextbook(e);
+    if (this.time) clearTimeout(this.time);
+    this.time = setTimeout(() => {
+      this.getTextbook(e);
+    }, 500);
   }
   //分页切换
   pageIndexChange(e: any) {
@@ -454,7 +458,7 @@ export class TextbookComponent implements OnInit {
     console.log(this.limit);
     // this.onAllChecked(false)
     this.pageIndex = 1;
-    this.getTextbook();
+    this.getTextbook(this.searchValue);
   }
   //全选
   onAllChecked(checked: boolean) {

+ 1 - 1
projects/textbook/src/modules/common/textbook-details/textbook-details.component.html

@@ -14,7 +14,7 @@
 
 @if (this.tbookSer.profile.identity == '工作联系人' ||
 this.tbookSer.profile.user?.department == textBook?.department) {
-<nz-tabset style="margin: 0 20px">
+<nz-tabset style="margin: 0 24px">
   <nz-tab nzTitle="教材申报书及附件">
     <ng-container *ngTemplateOutlet="one"></ng-container>
   </nz-tab>

+ 3 - 0
projects/textbook/src/modules/common/textbook-details/textbook-details.component.scss

@@ -128,4 +128,7 @@
 
 ::ng-deep .ant-tabs-tab-btn:active {
   color: #e97488;
+}
+::ng-deep .ant-page-header {
+  padding: 0 !important;
 }

+ 80 - 25
projects/textbook/src/modules/nav-province-contact/activity/activity.component.html

@@ -4,7 +4,8 @@
       <span nz-icon nzType="left" nzTheme="outline"></span>返回
     </div>
   </nz-breadcrumb>
-  <nz-page-header-title>{{activity?.get('name')?activity?.get('name'):'创建评委活动'}}
+  <nz-page-header-title
+    >{{ activity?.get("name") ? activity?.get("name") : "创建评委活动" }}
   </nz-page-header-title>
 </nz-page-header>
 <div class="edit-content">
@@ -12,29 +13,49 @@
     <nz-tab nzTitle="活动规则设置">
       @if (active == 0) {
       <div class="basic">
-        <div class="title">基本信息</div>
+        <div class="title" style="margin-top: 10px;" >基本信息</div>
         <ul nz-row nzJustify="space-between">
           <li nz-col nzSpan="11">
             <p>评审活动名称<span>*</span></p>
-            <input nz-input placeholder="请输入评审活动名称" [(ngModel)]="name" type="text" />
+            <input
+              nz-input
+              placeholder="请输入评审活动名称"
+              [(ngModel)]="name"
+              type="text"
+            />
           </li>
           <li nz-col nzSpan="11">
             <p>开始时间<span></span></p>
-            <nz-date-picker nzShowTime nzFormat="yyyy-MM-dd HH:mm:ss" [(ngModel)]="startDate"></nz-date-picker>
+            <nz-date-picker
+              nzShowTime
+              nzFormat="yyyy-MM-dd HH:mm:ss"
+              [(ngModel)]="startDate"
+            ></nz-date-picker>
           </li>
           <li nz-col nzSpan="11">
             <p>结束时间<span></span></p>
-            <nz-date-picker nzShowTime nzFormat="yyyy-MM-dd HH:mm:ss" [(ngModel)]="deadline"></nz-date-picker>
+            <nz-date-picker
+              nzShowTime
+              nzFormat="yyyy-MM-dd HH:mm:ss"
+              [(ngModel)]="deadline"
+            ></nz-date-picker>
           </li>
         </ul>
 
-        <button (click)="save()" class="btn save" nz-button nzType="primary">保存</button>
-        <button (click)="reset()" class="btn replay" nz-button nzType="primary">重置</button>
+        <button (click)="save()" class="btn save" nz-button nzType="primary">
+          保存
+        </button>
+        <button (click)="reset()" class="btn replay" nz-button nzType="primary">
+          重置
+        </button>
         <div class="title">评审规则</div>
         <ul nz-row nzJustify="space-between">
           <li nz-col nzSpan="11">
             <p>总分值计算方式<span>*</span></p>
-            <nz-radio-group [(ngModel)]="calculation" (ngModelChange)="changeCalculation()">
+            <nz-radio-group
+              [(ngModel)]="calculation"
+              (ngModelChange)="changeCalculation()"
+            >
               <label nz-radio nzValue="mean">平均数</label>
               <label nz-radio nzValue="truncatedMean">截尾平均数</label>
             </nz-radio-group>
@@ -44,52 +65,86 @@
             @if(reviewDetails?.url){
             <a target="_blank" [href]="reviewDetails?.url">
               <span nz-icon nzType="file" nzTheme="outline"></span>
-              {{reviewDetails?.name}}
+              {{ reviewDetails?.name }}
             </a>
             }
 
             <div class="uploadBtn">
-              <app-comp-upload [type]="'pdf'" (change)="upload($event)" title="上传评审细则文件"></app-comp-upload>
+              <app-comp-upload
+                [type]="'pdf'"
+                (change)="upload($event)"
+                title="上传评审细则文件"
+              ></app-comp-upload>
             </div>
-
           </li>
         </ul>
         <div class="title">
           评审组
-          <button (click)="creatReviewGroup()" class="btn replay" nz-button nzType="primary">创建评审组</button>
+          <button
+            (click)="creatReviewGroup()"
+            class="btn replay"
+            nz-button
+            nzType="primary"
+          >
+            创建评审组
+          </button>
         </div>
         @if (expertGroupList.length>0) {
-        <ul class="reviewGroup" >
+        <ul class="reviewGroup">
           @for (item of expertGroupList; track $index) {
           <li>
             <div>
-              <div>{{item?.get('name')||'未命名'}}</div>
-              <p>更新时间:{{item?.get('updatedAt')|date:'yyyy-MM-dd HH:mm:ss'}}</p>
+              <div>{{ item?.get("name") || "未命名" }}</div>
+              <p>
+                更新时间:{{
+                  item?.get("updatedAt") | date : "yyyy-MM-dd HH:mm:ss"
+                }}
+              </p>
             </div>
             <div>
-              <button class="btn replay" nz-button nzType="primary" (click)="goUrl('/nav-province-contact/manage/review-edit/'+item.id)">编辑</button><br>
-              <button (click)="deleteGroup($index)" nz-button nzType="text" nzDanger>删除</button>
+              <button
+                class="btn replay"
+                nz-button
+                nzType="primary"
+                (click)="
+                  goUrl('/nav-province-contact/manage/review-edit/' + item.id)
+                "
+              >
+                编辑</button
+              ><br />
+              <button
+                (click)="deleteGroup($index)"
+                nz-button
+                nzType="text"
+                nzDanger
+              >
+                删除
+              </button>
             </div>
           </li>
           }
-
         </ul>
         }@else {
-        <nz-empty class="empty" nzNotFoundImage="simple" nzNotFoundContent="还没有评审组"></nz-empty>
+        <nz-empty
+          class="empty"
+          nzNotFoundImage="simple"
+          nzNotFoundContent="还没有评审组"
+        ></nz-empty>
         }
-
-
       </div>
-
-
       }
     </nz-tab>
     <nz-tab nzTitle="评审明细">
-
+      @if (active == 1) {
+      <app-review-details
+        [listOfFilter]="listOfFilter"
+        [filterObj]="filterObj"
+      ></app-review-details>
+      }
     </nz-tab>
   </nz-tabset>
 </div>
 
 <div class="loading" [hidden]="!saveLoading">
   <nz-spin nzSimple [nzSize]="'large'"></nz-spin>
-</div>
+</div>

+ 30 - 13
projects/textbook/src/modules/nav-province-contact/activity/activity.component.ts

@@ -24,6 +24,7 @@ import { NzSpinModule } from 'ng-zorro-antd/spin';
 import { MatDialogRef } from '@angular/material/dialog';
 import { DatePipe } from '@angular/common';
 import { NzModalService } from 'ng-zorro-antd/modal';
+import { ReviewDetailsComponent } from '../components/review-details/review-details.component'
 
 @Component({
   selector: 'app-activity',
@@ -37,7 +38,6 @@ import { NzModalService } from 'ng-zorro-antd/modal';
     TextbookComponent,
     NzInputModule,
     NzDatePickerModule,
-    NzButtonModule,
     NzGridModule,
     NzMessageModule,
     NzRadioModule,
@@ -45,14 +45,22 @@ import { NzModalService } from 'ng-zorro-antd/modal';
     CompUploadComponent,
     MatDialogModule,
     NzSpinModule,
+    ReviewDetailsComponent
   ],
   providers: [DatePipe],
-
   standalone: true,
 })
 export class ActivityComponent implements OnInit {
   active: number = 0;
   eduProcess: Parse.Object | undefined;
+
+  listOfFilter: Array<any> = []; //评审组
+  filterObj:any = {
+    showGroup:true,
+    contained: [],
+    bookMap:{},//教材对应评审组结构{booid:评审组名称}
+  };
+
   constructor(
     private activeRoute: ActivatedRoute,
     public tbookSer: textbookServer,
@@ -79,18 +87,9 @@ export class ActivityComponent implements OnInit {
         }
         this.eduProcess = res;
         this.refersh()
-
       }
     });
   }
-  back() {
-    history.back();
-    // this.router.navigate(['/nav-admin/manage/user'], {
-    //   queryParams: { page: this.activeRoute.snapshot.queryParamMap.get('page') },
-    // });
-  }
-
-
   async refersh() {
     await this.getActivity()
     await this.getExpertGroup()
@@ -173,8 +172,22 @@ export class ActivityComponent implements OnInit {
     query.equalTo('eduProcess', this.eduProcess?.id)
     query.notEqualTo('isDeleted', true)
     query.descending('updatedAt')//大到小
+    query.include('textbookList')
     this.expertGroupList = await query.find()
     console.log(this.expertGroupList)
+    this.expertGroupList.forEach(item=>{
+      this.listOfFilter.push({
+        text:item.get('name'),
+        value:item.id
+      })
+      item.get('textbookList')?.forEach( (book:Parse.Object)=> {
+        this.filterObj.bookMap[book.id] = {
+          name:item.get('name'),
+          id:item.id
+        }
+        this.filterObj.contained.push(book.id)
+      });
+    })
   }
   async deleteGroup(index: number) {
     this.modal.confirm({
@@ -191,8 +204,6 @@ export class ActivityComponent implements OnInit {
       nzCancelText: '取消',
       nzOnCancel: () => console.log('Cancel')
     });
-
-    
   }
   /**创建评审组弹框 */
   creatReviewGroup() {
@@ -220,6 +231,12 @@ export class ActivityComponent implements OnInit {
   goUrl(url:string){
     this.router.navigate([url])
   }
+  back() {
+    history.back();
+    // this.router.navigate(['/nav-admin/manage/user'], {
+    //   queryParams: { page: this.activeRoute.snapshot.queryParamMap.get('page') },
+    // });
+  }
 }
 
 

+ 21 - 11
projects/textbook/src/modules/nav-province-contact/activity/review-edit/review-edit.component.html

@@ -1,14 +1,21 @@
-<nz-page-header>
-  <nz-breadcrumb nz-page-header-breadcrumb>
-    <div class="back" (click)="back()">
-      <span nz-icon nzType="left" nzTheme="outline"></span>返回
-    </div>
-  </nz-breadcrumb>
-  <nz-page-header-title
-    >{{ expertGroup?.get("name") || "-" }}
-  </nz-page-header-title>
-</nz-page-header>
+<div class="site-page-header">
+  <nz-page-header>
+    <nz-breadcrumb nz-page-header-breadcrumb>
+      <div class="back" (click)="back()">
+        <span nz-icon nzType="left" nzTheme="outline"></span>返回
+      </div>
+    </nz-breadcrumb>
+    <nz-page-header-title
+      >{{ expertGroup?.get("name") || "-" }}
+    </nz-page-header-title>
+  </nz-page-header>
+  <nz-tabset [(nzSelectedIndex)]="active">
+    <nz-tab nzTitle="教材申报书及附件"> </nz-tab>
+    <nz-tab nzTitle="教材评审明细"> </nz-tab>
+  </nz-tabset>
+</div>
 <div class="edit-content">
+  @if (active == 0) {
   <div class="edit-comp">
     <div class="title">设置评审教材</div>
     <nz-radio-group
@@ -35,7 +42,7 @@
           @for (item of allTextbook; track $index) { @if (!showAll) {
           <div [hidden]="$index >= 8" class="text-name">
             {{ item.get("title") }}
-            <span [hidden]="$index >= 8-1 || $index == allTextbook.length - 1"
+            <span [hidden]="$index >= 8 - 1 || $index == allTextbook.length - 1"
               >;</span
             >
           </div>
@@ -190,4 +197,7 @@
       </button>
     </div>
   </div>
+  } @else if (active == 1) {
+  <app-review-details [filterObj]="reviewFilterObj"></app-review-details>
+  }
 </div>

+ 21 - 9
projects/textbook/src/modules/nav-province-contact/activity/review-edit/review-edit.component.scss

@@ -1,10 +1,19 @@
-.back {
-  font-family: PingFang SC;
-  font-size  : 14px;
-  font-weight: 400;
-  line-height: 22px;
-  text-align : left;
-  cursor     : pointer;
+.site-page-header {
+  position        : sticky;
+  top             : 0;
+  z-index         : 9;
+  padding         : 24px 24px 10px;
+  background-color: white;
+  font-family     : PingFang SC;
+
+  .back {
+    font-family: PingFang SC;
+    font-size  : 14px;
+    font-weight: 400;
+    line-height: 22px;
+    text-align : left;
+    cursor     : pointer;
+  }
 }
 
 .edit-content {
@@ -49,8 +58,8 @@
         }
 
         .show-text {
-          cursor: pointer;
-          color : #066BE7;
+          cursor     : pointer;
+          color      : #066BE7;
           margin-left: 20px;
           flex-shrink: 0;
         }
@@ -153,4 +162,7 @@
 
 ::ng-deep .ant-tabs-tab-btn:active {
   color: #e97488;
+}
+::ng-deep .ant-page-header {
+  padding: 0 !important;
 }

+ 12 - 5
projects/textbook/src/modules/nav-province-contact/activity/review-edit/review-edit.component.ts

@@ -11,6 +11,8 @@ import { NzRadioModule } from 'ng-zorro-antd/radio';
 import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
 import { NzModalService } from 'ng-zorro-antd/modal';
 import { NzMessageService } from 'ng-zorro-antd/message';
+import { ReviewDetailsComponent } from '../../components/review-details/review-details.component'
+
 @Component({
   selector: 'app-review-edit',
   templateUrl: './review-edit.component.html',
@@ -23,6 +25,7 @@ import { NzMessageService } from 'ng-zorro-antd/message';
     TextbookComponent,
     NzRadioModule,
     NzCheckboxModule,
+    ReviewDetailsComponent
   ],
   standalone: true,
 })
@@ -38,18 +41,15 @@ export class ReviewEditComponent implements OnInit {
   }
   radio: string = 'all';
   radioReview: string = 'all';
-
+  active:number = 0
   filterObj: any = {
     showMore: true, //显示更多字段
     isCheck: true,
-    noStared: true,
+    // noStared: true,
     status: ['200'],
     notContained: [], //排除id
     showText: true,
     btns: {
-      // reject: true, //退回教材
-      // star: true, //移除推荐
-      // export: true,
     },
   };
   modalValue: string = '';
@@ -60,6 +60,10 @@ export class ReviewEditComponent implements OnInit {
   allTextbook:Array<any> = [] //已选择教材列表
   showAll:boolean = false
 
+  reviewFilterObj:any = {
+    contained: [],
+  }
+
   constructor(
     private activeRoute: ActivatedRoute,
     public tbookSer: textbookServer,
@@ -90,6 +94,8 @@ export class ReviewEditComponent implements OnInit {
       this.expertGroup.get('reviewList')?.forEach((item: any) => {
         this.setOfCheckedProfileAll.add(item.id || item.objectId);
       });
+      //赋值给评审详情组建
+      this.reviewFilterObj.contained = Array.from(this.setOfCheckedTextbookAll)
       await this.getExpertGroup()
       this.radio = res?.get('checkTextbook') ?? 'all';
       this.getProfile()
@@ -242,6 +248,7 @@ export class ReviewEditComponent implements OnInit {
       this.expertGroup?.set('checkReview', this.radioReview);
     }
     await this.expertGroup?.save();
+    this.reviewFilterObj.contained = Array.from(this.setOfCheckedTextbookAll)
     this.message.success('设置成功');
     // this.refresh()
   }

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

@@ -1,3 +1,106 @@
-<p>
-  review-details works!
-</p>
+<div class="textbook-table">
+  <div class="tool">
+    <div class="search">
+      <nz-input-group style="width: 280px" [nzPrefix]="prefixTemplateUser">
+        <input
+          type="text"
+          nz-input
+          placeholder="输入教材名称 / ISBN / 作者名搜索"
+          [(ngModel)]="searchValue"
+          (ngModelChange)="onSearch($event)"
+        />
+      </nz-input-group>
+      <ng-template #prefixTemplateUser
+        ><span nz-icon nzType="search"></span
+      ></ng-template>
+    </div>
+    <div class="sbt" (click)="export()">导出评审明细</div>
+  </div>
+  <nz-table
+    #tableData
+    [nzData]="reviewList"
+    [nzTotal]="count"
+    [(nzPageSize)]="limit"
+    [nzPageIndex]="pageIndex"
+    style="margin: 10px 0"
+    [nzLoading]="loading"
+    nzSize="middle"
+    [nzFrontPagination]="false"
+    [nzScroll]="{ x: (maxWidth || '800') + 'px', y: '580px' }"
+    nzTableLayout="fixed"
+    [nzPageSizeOptions]="[10, 20, 30, 40, 50]"
+    nzShowSizeChanger
+    (nzPageIndexChange)="pageIndexChange($event)"
+    (nzPageSizeChange)="onPageSizeChange($event)"
+  >
+    <thead>
+      <tr>
+        <th nzEllipsis nzWidth="120px" nzLeft>申报编号</th>
+        <th nzEllipsis nzWidth="120px">教材名称</th>
+        @if (filterObj.showGroup) {
+        <th
+          nzEllipsis
+          nzWidth="120px"
+          [nzShowFilter]="true"
+          [nzFilters]="listOfFilter"
+          (nzFilterChange)="listOfColumns.lang.onChange($event)"
+        >
+          所属评审组
+        </th>
+        }
+        <th nzEllipsis nzWidth="80px">评审专家</th>
+        <th nzEllipsis nzWidth="120px">提交时间</th>
+        <th nzEllipsis nzWidth="80px" nzRight>分值</th>
+      </tr>
+    </thead>
+    @if (reviewList.length > 0) {
+    <tbody>
+      @for (data of reviewList; track data.id) {
+      <tr>
+        <td nzEllipsis nzLeft>
+          {{ data?.get("eduTextbook")?.get("code") ?? "-" }}
+        </td>
+        <td
+          nzEllipsis
+          class="activeTd"
+          (click)="toUrl('/common/textbook/details/' + data.id)"
+          nz-popover
+          [nzPopoverContent]="contentTemplatetitle"
+        >
+          {{ data?.get("eduTextbook")?.get("title") || "-" }}
+          <ng-template #contentTemplatetitle>
+            <div style="max-width: 400px">
+              {{ data?.get("eduTextbook")?.get("title") || "-" }}
+            </div>
+          </ng-template>
+        </td>
+        @if (filterObj.showGroup) {
+        <td nzEllipsis>
+          {{ filterObj.bookMap[data?.get("eduTextbook")?.id].name }}
+        </td>
+        }
+        <td nzEllipsis nz-popover [nzPopoverContent]="contentTemplateName">
+          {{ data?.get("profile")?.get("user")?.get("name") || "-" }}
+          <ng-template #contentTemplateName>
+            <div style="max-width: 400px">
+              {{ data?.get("profile")?.get("user")?.get("name") || "-" }}
+            </div>
+          </ng-template>
+        </td>
+        <td nzEllipsis>
+          {{ data.updatedAt | date : "yyyy-MM-dd HH:mm" }}
+        </td>
+        <td nzEllipsis nzRight>{{ data?.get("score") ?? "-" }}</td>
+      </tr>
+      }
+    </tbody>
+    }
+  </nz-table>
+  @if (reviewList.length == 0) {
+  <nz-empty nzNotFoundImage="/img/group-empty.png"></nz-empty>
+  }
+
+  <div class="loading" [hidden]="!showLoading">
+    <nz-spin nzSimple [nzSize]="'large'"></nz-spin>
+  </div>
+</div>

+ 93 - 0
projects/textbook/src/modules/nav-province-contact/components/review-details/review-details.component.scss

@@ -0,0 +1,93 @@
+.activeTd{
+  cursor: pointer;
+}
+.tool{
+  display: flex;
+  justify-content: space-between;
+  .sbt{
+    padding: 6px 10px;
+    background: #E8F5FC;
+    font-family: PingFang SC;
+    font-size: 14px;
+    font-weight: 400;
+    /* line-height: 20px; */
+    text-align: center;
+    color: #0054C3;
+    border-radius: 4px;
+    cursor: pointer;
+  }
+}
+.activeTd{
+  color: #c6233f;
+}
+// 选中,批量操作区域
+.batch-toolbar-modal{
+  position: fixed;
+  display: flex;
+  justify-content: center;
+  bottom: 80px;
+  // left: calc(50% - 134px);
+  left: calc(50% - 328px);
+  -webkit-transform: translate(0);
+  transform: translate(0);
+}
+.batch-toolbar {
+  display: flex;
+  align-items: center;
+  height: 56px;
+  // min-width: 600px;
+  background: #fff;
+  border: 1px solid #e5e6eb;
+  box-sizing: border-box;
+  box-shadow: 0 16px 32px -10px rgba(4, 24, 115, .1);
+  border-radius: 4px;
+  button{
+      color:#545968;
+  }
+}
+.batch-toolbar .styles_counter__18S08 {
+  color: #fff;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+  background: #C6233F;
+  width: 100px;
+  font-size: 12px;
+  border-top-left-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+.batch-toolbar .batch-toolbar-actions {
+  display: flex;
+  margin: auto;
+  padding: 0 20px;
+}
+.batch-toolbar .styles_cancel__AARoT {
+  font-size: 16px;
+  border-left: 1px solid #a9aeb8;
+  // padding-left: 20px;
+  display: flex;
+  justify-content: center;
+  width: 128px;
+}
+.batch-toolbar .styles_counter__18S08 .styles_num__178Wa {
+  font-size: 24px;
+  margin-left: 8px;
+}
+
+.loading{
+  position: fixed;
+  z-index: 99;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  text-align: center;
+  height: 100vh;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: rgb(0 0 0 / 30%);
+}
+::ng-deep .nz-table-hide-scrollbar{
+  scrollbar-color: auto;
+}

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

@@ -1,14 +1,297 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, Input, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { NzSpaceModule } from 'ng-zorro-antd/space';
+import { CommonCompModule } from '../../../../services/common.modules';
+import { ActivatedRoute, Router } from '@angular/router';
+import { NzMessageModule } from 'ng-zorro-antd/message';
+import { NzMessageService } from 'ng-zorro-antd/message';
+import Parse from 'parse';
+import { textbookServer } from '../../../../services/textbook';
+import { NzModalService } from 'ng-zorro-antd/modal';
+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';
 
 @Component({
   selector: 'app-review-details',
   templateUrl: './review-details.component.html',
   styleUrls: ['./review-details.component.scss'],
+  imports: [
+    CommonModule,
+    NzSpaceModule,
+    CommonCompModule,
+    NzMessageModule,
+    NzEmptyModule,
+    NzPopoverModule,
+  ],
+  providers: [DatePipe],
+  standalone: true,
 })
-export class ReviewDetailsComponent  implements OnInit {
+export class ReviewDetailsComponent implements OnInit {
+  reviewList: Array<Parse.Object> = [];
+  count: number = 0;
+  @Input('limit') limit: number = 10;
+  pageIndex: number = 1;
+  loading: boolean = false;
+  @Input('maxWidth') maxWidth: any; //最大宽度
+  @Input('eduProcess') eduProcess?: Parse.Object; //流程id,verify存在时需要
 
-  constructor() { }
+  @Input('listOfFilter') listOfFilter: Array<any> = []; //评审组
+  @Input('filterObj') filterObj: any = {
+    showGroup: false,
+    contained: [],
+    bookMap: {}, //教材对应评审组结构{booid:评审组名称}
+  };
+  searchValue: string = '';
+  listOfColumns: any = {
+    lang: {
+      // listOfFilter: [{ value: '中文', text: '中文' }],
+      onChange: (data: Array<string>) => {
+        console.log(data);
+        if (data?.length < 1) {
+          this.filterObj.contained = Object.keys(this.filterObj.bookMap);
+        } else {
+          this.filterObj.contained = [];
+          for (const key in this.filterObj.bookMap) {
+            const item = this.filterObj.bookMap[key];
+            if (data.includes(item.id)) {
+              this.filterObj.contained.push(key);
+            }
+          }
+        }
+        this.getTextbook(this.searchValue);
+      },
+    },
+  };
 
-  ngOnInit() {}
+  showLoading: boolean = false; //全局
+  time: any;
 
+  constructor(
+    private activeRoute: ActivatedRoute,
+    public tbookSer: textbookServer,
+    private router: Router,
+    private msg: NzMessageService,
+    public dialog: MatDialog,
+    private route: Router,
+    private datePipe: DatePipe,
+    private modal: NzModalService
+  ) {}
+
+  ngOnInit() {
+    this.getTextbook();
+  }
+  async getTextbook(val?: string, exported?: boolean): Promise<any[] | void> {
+    if (this.loading) return;
+    if(!exported) this.loading = true;
+    try {
+      let queryParams: any = {
+        where: {
+          $or: [
+            {
+              eduTextbook: {
+                $inQuery: {
+                  where: {
+                    $or: [
+                      {
+                        title: { $regex: `.*${val || ''}.*` },
+                      },
+                      {
+                        childrens: {
+                          $inQuery: {
+                            where: {
+                              $or: [
+                                {
+                                  ISBN: { $regex: `.*${val || ''}.*` },
+                                },
+                                {
+                                  author: { $regex: `.*${val || ''}.*` },
+                                },
+                              ],
+                            },
+                            className: 'EduTextbookVolume',
+                          },
+                        },
+                      },
+                    ],
+                  },
+                  className: 'EduTextbook',
+                },
+              },
+            },
+            {
+              profile: {
+                $inQuery: {
+                  where: {
+                    $or: [
+                      {
+                        user: {
+                          $inQuery: {
+                            where: {
+                              $or: [
+                                {
+                                  name: { $regex: `.*${val || ''}.*` },
+                                },
+                              ],
+                            },
+                            className: '_User',
+                          },
+                        },
+                      },
+                    ],
+                  },
+                  className: 'Profile',
+                },
+              },
+            },
+          ],
+          eduTextbook: { $in: this.filterObj.contained },
+        },
+      };
+      let query = Parse.Query.fromJSON('EduReview', queryParams);
+      this.eduProcess?.id && query.equalTo('eduProcess', this.eduProcess.id);
+      query.descending('updatedAt');
+      query.notEqualTo('isDeleted', true);
+      query.include('eduTextbook', 'profile', 'profile.user');
+      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.reviewList = await query.find();
+      console.log(this.reviewList);
+      this.loading = false;
+    } catch (err) {
+      console.warn(err);
+      this.msg.error('获取超时');
+    }
+    this.loading = false;
+  }
+  onSearch(e: string) {
+    this.pageIndex = 1;
+    console.log(e);
+    if (this.time) clearTimeout(this.time);
+    this.time = setTimeout(() => {
+      this.getTextbook(e);
+    }, 500);
+  }
+  //分页切换
+  pageIndexChange(e: any) {
+    console.log(e);
+    this.pageIndex = e;
+    this.getTextbook(this.searchValue);
+  }
+  //切换分页条数
+  onPageSizeChange($event: any): void {
+    console.log(this.limit);
+    // this.onAllChecked(false)
+    this.pageIndex = 1;
+    this.getTextbook();
+  }
+
+  toUrl(url: string, param?: Object) {
+    console.log(url);
+    if (param) {
+      this.route.navigate([url, param]);
+      return;
+    }
+    this.route.navigate([url]);
+  }
+
+  //导出表格
+  async export() {
+    if (this.showLoading) return;
+    this.showLoading = true;
+    try {
+      let data: any = await this.getTextbook('', true);
+      let table = `<table border="1px" cellspacing="0" cellpadding="0">
+        <thead>
+          <tr>
+            <th>序号</th>
+            <th>申报教材名称</th>
+            <th>所属评审组</th>
+            ${this.filterObj.showGroup ? '<th>评审专家</th>' : ''}
+            <th>提交时间</th>
+            <th>分值</th>
+          </tr>
+        </thead>
+        <tbody>
+        `;
+      let _body = '';
+      for (var row = 0; row < data.length; row++) {
+        _body += '<tr>';
+        _body += '<td>';
+        _body += `${row + 1}`;
+        _body += '</td>';
+
+        _body += '<td>';
+        _body += `&nbsp;${data[row]?.get('eduTextbook')?.get('title') || ''}`;
+        _body += '</td>';
+
+        if(this.filterObj.showGroup){
+          _body += '<td>';
+          _body += ` &nbsp;${
+            this.filterObj.bookMap[data[row]?.get('eduTextbook')?.id].name || '-'
+          }`;
+          _body += '</td>';
+        }
+
+        _body += '<td>';
+        _body += `${
+          data[row]?.get('profile')?.get('user')?.get('name') || '-'
+        }`;
+        _body += '</td>';
+
+        _body += '<td>';
+        _body += `&nbsp;${this.datePipe.transform(
+          data[row]?.updatedAt,
+          'yyyy-MM-dd HH:mm:ss'
+        )}`;
+        _body += '</td>';
+
+        _body += '<td>';
+        _body += `${data[row]?.get('score') ?? '-'}`;
+        _body += '</td>';
+
+        _body += '</tr>';
+      }
+      table += _body;
+      table += '</tbody>';
+      table += '</table>';
+      let title = '评审详情表';
+      this.excel(table, `${title}.xls`);
+      this.showLoading = false;
+    } catch (err) {
+      console.log(err);
+      this.showLoading = false;
+      this.msg.error('导出超时');
+    }
+  }
+  excel(data: any, filename: string) {
+    let html =
+      "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>";
+    html +=
+      '<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">';
+    html += '<meta http-equiv="content-type" content="application/vnd.ms-excel';
+    html += '; charset=UTF-8">';
+    html += '<head>';
+    html += '</head>';
+    html += '<body>';
+    html += data;
+    html += '</body>';
+    html += '</html>';
+    let uri =
+      'data:application/vnd.ms-excel;charset=utf-8,' + encodeURIComponent(html);
+    let link = document.createElement('a');
+    link.href = uri;
+    link.download = `${filename}`;
+    document.body.appendChild(link);
+    link.click();
+    document.body.removeChild(link);
+  }
 }