Browse Source

外部评审权限功能

warrior 3 months ago
parent
commit
72a9c80e12

+ 4 - 0
projects/textbook/src/modules/common/not-found404/not-found404.component.html

@@ -0,0 +1,4 @@
+<nz-result nzStatus="404" nzTitle="404" nzSubTitle="抱歉,你访问的页面不存在">
+  <div nz-result-extra>
+  </div>
+</nz-result>

+ 0 - 0
projects/textbook/src/modules/common/not-found404/not-found404.component.scss


+ 24 - 0
projects/textbook/src/modules/common/not-found404/not-found404.component.spec.ts

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

+ 18 - 0
projects/textbook/src/modules/common/not-found404/not-found404.component.ts

@@ -0,0 +1,18 @@
+import { Component, OnInit } from '@angular/core';
+import { NzResultModule } from 'ng-zorro-antd/result';
+@Component({
+  selector: 'app-not-found404',
+  templateUrl: './not-found404.component.html',
+  styleUrls: ['./not-found404.component.scss'],
+  imports: [
+    NzResultModule,
+  ],
+  standalone: true,
+})
+export class NotFound404Component  implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {}
+
+}

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

@@ -7,7 +7,7 @@
       <div class="title-name">纸质教材PDF文件</div>
       <div>
         @for (item of eduTextbookVolume?.get('collectFiles'); track $index) {
-        <a (click)="openUrl(item.url)">{{ item.name }}</a>
+        <a (click)="openUrl(item.url, true)">{{ item.name }}</a>
         }
       </div>
     </div>
@@ -44,7 +44,7 @@
       <div>
         @for (item of eduTextbookVolume?.get('collectDigitFiles'); track $index)
         {
-        <a (click)="openUrl(item.url)">{{ item.name }}</a>
+        <a (click)="openUrl(item.url, true)">{{ item.name }}</a>
         }
       </div>
       }

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

@@ -111,12 +111,16 @@ export class UploadCollectComponent implements OnInit {
     return true;
   }
 
-  async openUrl(url: string) {
+  async openUrl(url: string, isFile?:boolean) {
+    let path = window.location
     if (
-      this.eduTextbookVolume?.get('editionUnit') ===
-      this.tbookSer.profile.user?.department?.name
+      isFile && ((this.eduTextbookVolume?.get('editionUnit') ===
+      this.tbookSer.profile?.user?.department?.name)
+      ||
+      (path.pathname.indexOf(`/external/review/detail/${this.eduTextbookVolume?.get('eduTextbook')?.id}`) != -1
+      && Parse.User.current()?.get('username') === '145review'))
     ) {
-      url = await this.ossProvider?.signatureUrl(url,{expires:120});
+      url = await this.ossProvider?.signatureUrl(url,{expires:180});
       this.modal.warning({
         nzTitle: '提示',
         nzContent: '教材文件临时链接已打开,请勿外泄。'

+ 45 - 10
projects/textbook/src/modules/review-verify/auth.guard.ts

@@ -7,11 +7,13 @@ import {
 import { Observable } from 'rxjs';
 import { Router } from '@angular/router';
 import { textbookServer } from '../../services/textbook';
+import Parse from 'parse';
+
 @Injectable({
   providedIn: 'root',
 })
 export class AuthGuard implements CanActivate {
-  LoginPage = '/user/login';
+  LoginPage = 'external/404';
   constructor(private tbookSer: textbookServer, private router: Router) {}
   canActivate(
     next: ActivatedRouteSnapshot,
@@ -36,24 +38,57 @@ export class AuthGuard implements CanActivate {
         .then((data) => {
           console.log(data.data);
           if (data.data.rs == 0) {
-            // window.location.href =
-            //   'https://audit.hep.com.cn/admin/401?noGoBack=0';
+            window.location.href =
+              'https://audit.hep.com.cn/admin/401?noGoBack=0';
             this.router.navigate([this.LoginPage]);
             resolve(false);
+            // Parse.User.logIn('145review', 'review-textbook145').then((user) => {
+            //     resolve(true);
+            // })
+            // Parse.User.become('r:4d692312d4b08d4120981152e67428f8')
+            //   .then((user) => resolve(true))
+            //   .catch((err) => {
+            //     resolve(false);
+            //     this.router.navigate([this.LoginPage]);
+            //   });
           } else {
-            
-            resolve(true);
+            if (!Parse.User.current()?.id) {
+              fetch('https://145.tbook.com.cn/api/textbook/review/token', {
+                method: 'POST',
+                headers: {
+                  'Content-Type': 'application/json',
+                },
+              })
+                .then((response) => response.json())
+                .then(async (res) => {
+                  Parse.User.become(
+                    res?.token || 'r:4d692312d4b08d4120981152e67428f8'
+                  )
+                    .then((user) => resolve(true))
+                    .catch((err) => {
+                      console.log(err);
+                      window.location.href =
+                        'https://audit.hep.com.cn/admin/401?noGoBack=0';
+                      resolve(false);
+                    });
+                })
+                .catch((error) => {
+                  console.error('获取token失败:', error);
+                  resolve(false);
+                  this.router.navigate([this.LoginPage]);
+                });
+            } else {
+              resolve(true);
+            }
           }
         })
         .catch((error) => {
           console.error('Error:', error); // 处理错误
+          window.location.href =
+            'https://audit.hep.com.cn/admin/401?noGoBack=0';
+          resolve(false);
         });
     });
-    // if (this.tbookSer.profile.identity == '国家级管理员') {
-    //   return true;
-    // }
-    // this.router.navigate([this.LoginPage]);
-    // return false;
   }
 }
 export { CanActivate };

+ 6 - 5
projects/textbook/src/modules/review-verify/modules.routes.ts

@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
 import { mapToCanActivate, RouterModule, Routes } from '@angular/router';
 import { TextbookDetailsComponent } from './textbook-details/textbook-details.component';
 import { AuthGuard } from './auth.guard';
+import { NotFound404Component } from '../common/not-found404/not-found404.component';
 const routes: Routes = [
   {
     path: '',
@@ -13,14 +14,14 @@ const routes: Routes = [
     canActivate: mapToCanActivate([AuthGuard]),
     children: [
       {
-        path: 'detail/:id', //创建教材
-        component: TextbookDetailsComponent,
-      },
-      {
-        path: 'files/:id', //创建教材
+        path: 'detail/:id', 
         component: TextbookDetailsComponent,
       },
     ],
+  },
+  {
+    path: '404',
+    component: NotFound404Component,
   }
 ];
 @NgModule({

+ 51 - 1
projects/textbook/src/modules/review-verify/textbook-details/textbook-details.component.html

@@ -15,7 +15,7 @@
   @if(active == 0) {
   <ng-container *ngTemplateOutlet="Basics"></ng-container>
   } @else if (active == 1) {
-  <div class="content"></div>
+  <ng-container *ngTemplateOutlet="Files"></ng-container>
   }
 
   <ng-template #Basics>
@@ -638,4 +638,54 @@
       </div>
     </div>
   </ng-template>
+  <ng-template #Files>
+    <div class="content">
+    @if (textBook.type =='全册') {
+    <nz-collapse [nzBordered]="false">
+      @for (panel of eduTextbookVolumeParseList; 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) + "-" + textBook.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]="eduTextbookVolumeParseList[0]"
+    ></app-upload-collect>
+    }
+    </div>
+  </ng-template>
 </div>

+ 4 - 2
projects/textbook/src/modules/review-verify/textbook-details/textbook-details.component.ts

@@ -9,7 +9,7 @@ import { NzCollapseModule } from 'ng-zorro-antd/collapse';
 import { CommonModule } from '@angular/common';
 import { NzTabsModule } from 'ng-zorro-antd/tabs';
 import { NzTableModule } from 'ng-zorro-antd/table';
-
+import { UploadCollectComponent } from '../../nav-province-contact/components/upload-collect/upload-collect.component';
 @Component({
   selector: 'app-textbook-details',
   imports: [
@@ -21,6 +21,7 @@ import { NzTableModule } from 'ng-zorro-antd/table';
     CommonModule,
     NzTabsModule,
     NzTableModule,
+    UploadCollectComponent
   ],
   standalone: true,
   templateUrl: './textbook-details.component.html',
@@ -38,7 +39,7 @@ export class TextbookDetailsComponent implements OnInit {
   typeNumber: any;
   /** 申报类型*/
   type: any;
-
+  eduTextbookVolumeParseList:Array<Parse.Object> = []
   constructor(
     private router: Router,
     private activeRoute: ActivatedRoute
@@ -57,6 +58,7 @@ export class TextbookDetailsComponent implements OnInit {
         this.textBook = r?.toJSON();
         console.log(this.textBook);
         this.eduTextbookVolumeList = this.textBook?.childrens;
+        this.eduTextbookVolumeParseList = r?.get('childrens')
       }
     });
   }

+ 50 - 4
projects/textbook/src/services/shell.ts

@@ -33,9 +33,9 @@ export class shellServer {
       query.limit(4000);
       let r = await query.find();
       this.departments = {
-        '66865e1c5d561921fb4d6764':{name:'省级教育行政部门'},
-        '66865deea3ac903090a7b30b':{name:'有关部门(单位)教育司(局)'}
-      }
+        '66865e1c5d561921fb4d6764': { name: '省级教育行政部门' },
+        '66865deea3ac903090a7b30b': { name: '有关部门(单位)教育司(局)' },
+      };
       r?.forEach((item) => {
         this.departments[item.id] = item.toJSON();
       });
@@ -384,7 +384,7 @@ export class shellServer {
                 $inQuery: {
                   where: {
                     // editionUnit: unitName,
-                    collectStatus: {$ne: '200'},
+                    collectStatus: { $ne: '200' },
                     // collectStatus: '200',
                   },
                   className: 'EduTextbookVolume',
@@ -834,4 +834,50 @@ export class shellServer {
     console.log('update over');
     console.log(arr);
   }
+
+  /* 导出评审系统表格数据 */
+  async exportUrl() {
+    let unitName = '教材文件excel';
+    let query = new Parse.Query('EduTextbook');
+    query.notEqualTo('isDeleted', true);
+    query.notEqualTo('discard', true);
+    query.equalTo('render', true);
+    query.select('title', 'code');
+    query.containedIn('status', ['400']);
+    query.limit(10000);
+    query.skip(0);
+    let data = await query.find();
+    let table = `<table border="1px" cellspacing="0" cellpadding="0">
+        <thead>
+          <tr>
+            <th>教材名称</th>
+            <th>申报编号</th>
+            <th>文件链接</th>
+          </tr>
+        </thead>
+        <tbody>
+        `;
+    let _body = '';
+    for (var row = 0; row < data.length; row++) {
+      _body += '<tr>';
+
+      _body += '<td>';
+      _body += `${data[row]?.get('title') || '-'}`;
+      _body += '</td>';
+
+      _body += '<td>';
+      _body += `&nbsp;${data[row]?.get('code') || ''}`;
+      _body += '</td>';
+
+      _body += '<td>';
+      _body += `https://145.tbook.com.cn/external/review/detail/${data[row].id}`;
+      _body += '</td>';
+
+      _body += '</tr>';
+    }
+    table += _body;
+    table += '</tbody>';
+    table += '</table>';
+    this.excel(table, `${unitName}.xls`);
+  }
 }

+ 20 - 0
server/api/textbook/routes.js

@@ -194,5 +194,25 @@ async function setMobileSessionToken(user, reset) {
         return false
     }
 }
+
+router.post("/review/token", async (req, res) => {
+    let refer = req.headers["referer"] || req.headers["referered"];
+    // 检查referer来源
+    if (refer && refer.includes('https://145.tbook.com.cn')) {
+       Parse.User.logIn('145review', 'review-textbook145').then((user) => {
+            console.log(user?.get('sessionToken'));
+            response.json({
+                token: user?.get('sessionToken'),
+            })
+        }).catch(err=>{
+            goWrong(res, "invalid user");
+        })
+    }else{
+        response.json({
+            code: 404,
+        })
+    }
+})
+
 module.exports = router;
 export const textbookRouter = router;