Browse Source

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

ryanemax 7 months ago
parent
commit
aa0797b021
24 changed files with 375 additions and 89 deletions
  1. 3 3
      projects/textbook/src/app/textbook/textbook.component.html
  2. 35 0
      projects/textbook/src/app/textbook/textbook.component.ts
  3. 5 0
      projects/textbook/src/modules/login/account-info/account-info.component.ts
  4. 3 2
      projects/textbook/src/modules/nav-admin/page-role/page-role.component.html
  5. 14 2
      projects/textbook/src/modules/nav-admin/page-role/page-role.component.ts
  6. 3 2
      projects/textbook/src/modules/nav-admin/page-user/page-user.component.html
  7. 14 2
      projects/textbook/src/modules/nav-admin/page-user/page-user.component.ts
  8. 1 1
      projects/textbook/src/modules/nav-admin/user-edit/user-edit.component.html
  9. 20 2
      projects/textbook/src/modules/nav-admin/user-edit/user-edit.component.ts
  10. 16 15
      projects/textbook/src/modules/nav-author/components/attachment/attachment.component.html
  11. 7 7
      projects/textbook/src/modules/nav-author/components/attachment/attachment.component.ts
  12. 12 3
      projects/textbook/src/modules/nav-author/components/basic-in/basic-in.component.html
  13. 68 14
      projects/textbook/src/modules/nav-author/components/basic-in/basic-in.component.ts
  14. 7 7
      projects/textbook/src/modules/nav-author/components/textbook-pertain/textbook-pertain.component.html
  15. 3 2
      projects/textbook/src/modules/nav-province-contact/page-role/page-role.component.html
  16. 39 3
      projects/textbook/src/modules/nav-province-contact/page-role/page-role.component.ts
  17. 5 5
      projects/textbook/src/modules/nav-province-contact/page-textbook/page-textbook.component.html
  18. 39 2
      projects/textbook/src/modules/nav-province-contact/page-textbook/page-textbook.component.ts
  19. 19 4
      projects/textbook/src/modules/nav-province-contact/submitted/export-file/export-file.component.html
  20. 23 0
      projects/textbook/src/modules/nav-province-contact/submitted/export-file/export-file.component.scss
  21. 12 2
      projects/textbook/src/modules/nav-province-contact/submitted/export-file/export-file.component.ts
  22. 11 6
      projects/textbook/src/modules/nav-province-contact/submitted/submitted.component.html
  23. 5 5
      projects/textbook/src/services/auth.service.ts
  24. 11 0
      projects/textbook/src/services/textbook.ts

+ 3 - 3
projects/textbook/src/app/textbook/textbook.component.html

@@ -17,7 +17,7 @@
     @if (filterObj?.btns?.verify && count != 0) {
     <div
       class="sbt"
-      (click)="toUrl('/nav-province-contact/manage/submitted/' + eduProcess?.id)"
+      (click)="submitted()"
     >
       提交推荐教材列表
     </div>
@@ -215,7 +215,7 @@
                   style="color: #231c1f"
                 >
                   <span nz-icon nzType="export" nzTheme="outline"></span
-                  >导出函报文
+                  >导出申报书及附
                 </button>
               </li>
               } @if(filterObj.btns.reject){
@@ -429,7 +429,7 @@
                   style="color: #231c1f"
                 >
                   <span nz-icon nzType="export" nzTheme="outline"></span
-                  >导出函报文
+                  >导出申报书及附
                 </button>
               </li>
               } @if(filterObj.btns.reject){

+ 35 - 0
projects/textbook/src/app/textbook/textbook.component.ts

@@ -604,6 +604,41 @@ export class TextbookComponent implements OnInit {
     }
     this.route.navigate([url]);
   }
+  //报送
+  async submitted() {
+    if(this.eduProcess?.get('status') == '400'){
+      this.message.warning('已提交报送,无需重复提交')
+      this.toUrl(`/nav-province-contact/manage/submitted/${this.eduProcess?.id}`)
+      return
+    }
+    this.eduProcess?.set('status', '400');
+    this.eduProcess?.set('releaseDate', new Date());
+    let query = new Parse.Query('EduTextbook');
+    query.equalTo('eduProcess', this.eduProcess?.id);
+    query.notEqualTo('isDeleted', true);
+    query.notEqualTo('discard', true);
+    query.equalTo('render', true);
+    query.equalTo('recommend', true);
+    query.equalTo('status', '200');
+    let list = await query.find();
+    query.containedIn('approval', [
+      '首届全国教材建设奖优秀教材(高等教育类)教材',
+      '否',
+    ]);
+    let count = await query.count();
+    if (count > this.eduProcess?.get('num')) {
+      this.message.warning('当前推荐教材数量已超额')
+      return;
+    }
+    await this.eduProcess?.save();
+    for (let index = 0; index < list.length; index++) {
+      const item = list[index];
+      item.set('status', '400');
+      await item.save();
+    }
+    this.message.success('提交成功')
+    this.toUrl(`/nav-province-contact/manage/submitted/${this.eduProcess?.id}`)
+  }
   //导出
   async export() {
     let data: any = await this.getTextbook('', true);

+ 5 - 0
projects/textbook/src/modules/login/account-info/account-info.component.ts

@@ -195,6 +195,11 @@ export class AccountInfoComponent implements OnInit {
   async profileSave(params: any) {
     this.loading = true
     try {
+      if(!await this.tbookSer.userFind(params.phone)){
+        this.message.error('手机号已存在');
+        this.loading = false
+        return
+      }
       let queryDepart = new Parse.Query('Department');
       queryDepart.equalTo('objectId', this.companyId);
       queryDepart.select('objectId');

+ 3 - 2
projects/textbook/src/modules/nav-admin/page-role/page-role.component.html

@@ -338,7 +338,7 @@
 
 <nz-modal
   [(nzVisible)]="accountIsVisible"
-  nzTitle="添加账号(手机号及邮箱请至少填写一个,将发送登录账号)"
+  nzTitle="添加账号"
   (nzOnCancel)="handleCancel()"
   nzWidth="800px"
   nzCentered
@@ -425,7 +425,7 @@
           <div class="value">
             <input
               nz-input
-              maxlength="12"
+              maxlength="11"
               placeholder="请输入手机号"
               [(ngModel)]="account.phone"
               type="text"
@@ -476,6 +476,7 @@
       nz-button
       nzType="primary"
       style="background: #3e49b3; border: 1px #3e49b3"
+      [nzLoading]="isLoadingOne"
       (click)="accountComplete()"
     >
       确定

+ 14 - 2
projects/textbook/src/modules/nav-admin/page-role/page-role.component.ts

@@ -516,12 +516,18 @@ export class PageRoleComponent implements OnInit {
     console.log(this.account.password);
   }
   /* 添加账号 */
+  isLoadingOne:boolean = false
   async accountComplete(){
+    if(this.isLoadingOne) return
+    this.isLoadingOne = true
     this.account.email = this.account?.email.trim();
     this.account.phone = this.account?.phone.trim();
     this.account.name = this.account?.name.trim();
     this.account.password = this.account?.password.trim();
-    if(!this.authVrifly()) return
+    if(!await this.authVrifly()){
+      this.isLoadingOne = false
+      return
+    }
     try{
       let obj = Parse.Object.extend('_User');
       let user = new obj()
@@ -544,6 +550,7 @@ export class PageRoleComponent implements OnInit {
       profile?.set('email', this.account.email);
       profile?.set('identity', this.account.identity);
       let res = await profile?.save();
+      this.isLoadingOne = false
       this.accountIsVisible = false;
       this.account = null;
       this.modal.success({
@@ -556,11 +563,12 @@ export class PageRoleComponent implements OnInit {
     }
     catch(err:any){
       console.warn('添加用户错误',err);
+      this.isLoadingOne = false
       this.message.error(err?.Error || '错误:请检查用户邮箱或手机号是否已存在');
       return;
     }
   }
-  authVrifly():boolean | undefined{
+  async authVrifly():Promise< boolean | undefined>{
     this.account.email = this.account?.email.trim();
     this.account.phone = this.account?.phone.trim();
     this.account.name = this.account?.name.trim();
@@ -593,6 +601,10 @@ export class PageRoleComponent implements OnInit {
       this.message.error('密码格式错误,请填写6-18位非空字符串(数字、大小写字母或英文符号)');
       return;
     }
+    if(!await this.tbookSer.userFind(this.account.phone)){
+      this.message.error('手机号已存在');
+      return
+    }
     return true
   }
 

+ 3 - 2
projects/textbook/src/modules/nav-admin/page-user/page-user.component.html

@@ -324,7 +324,7 @@
           <div class="value">
             <input
               nz-input
-              maxlength="12"
+              maxlength="28"
               placeholder="请填写账号"
               [(ngModel)]="account.username"
               type="text"
@@ -336,7 +336,7 @@
           <div class="value">
             <input
               nz-input
-              maxlength="12"
+              maxlength="11"
               placeholder="请输入手机号"
               [(ngModel)]="account.phone"
               type="text"
@@ -386,6 +386,7 @@
     <button
       nz-button
       nzType="primary"
+      [nzLoading]="isLoadingOne"
       style="background: #3e49b3; border: 1px #3e49b3"
       (click)="accountComplete()"
     >

+ 14 - 2
projects/textbook/src/modules/nav-admin/page-user/page-user.component.ts

@@ -436,13 +436,19 @@ export class PageUserComponent implements OnInit {
     console.log(this.account.password);
   }
   /* 添加账号 */
+  isLoadingOne:boolean = false
   async accountComplete() {
+    if(this.isLoadingOne) return
+    this.isLoadingOne = true
     this.account.username = this.account?.username.trim();
     this.account.email = this.account?.email.trim();
     this.account.phone = this.account?.phone.trim();
     this.account.name = this.account?.name.trim();
     this.account.password = this.account?.password.trim();
-    if(!this.authVrifly()) return
+    if(!await this.authVrifly()){
+      this.isLoadingOne = false
+      return
+    }
     try {
       let obj = Parse.Object.extend('_User');
       let user = new obj();
@@ -468,6 +474,7 @@ export class PageUserComponent implements OnInit {
       profile?.set('email', this.account.email);
       profile?.set('identity', this.account.identity);
       let res = await profile?.save();
+      this.isLoadingOne = false
       this.accountIsVisible = false;
       this.account = null;
       this.modal.success({
@@ -480,13 +487,14 @@ export class PageUserComponent implements OnInit {
       });
     } catch (err: any) {
       console.warn('添加用户错误', err);
+      this.isLoadingOne = false
       this.message.error(
         err?.Error || '错误:请检查用户或邮箱及手机号是否已存在'
       );
       return;
     }
   }
-  authVrifly():boolean | undefined{
+  async authVrifly():Promise< boolean | undefined>{
     this.account.password = this.account?.password.trim();
     this.account.email = this.account?.email.trim();
     this.account.phone = this.account?.phone.trim();
@@ -522,6 +530,10 @@ export class PageUserComponent implements OnInit {
       this.message.error('密码格式错误,请填写6-18位非空字符串(数字、大小写字母或英文符号)');
       return;
     }
+    if(!await this.tbookSer.userFind(this.account.phone)){
+      this.message.error('手机号已存在');
+      return
+    }
     return true
   }
 }

+ 1 - 1
projects/textbook/src/modules/nav-admin/user-edit/user-edit.component.html

@@ -143,7 +143,7 @@
             <div class="lable">认证文件</div>
             <div class="value">
               @if (profile?.get('identityFile')) {
-              <a [href]="profile?.get('identityFile')">查看文件</a>
+              <a (click)="openUrl(profile?.get('identityFile'))">查看文件</a>
               }@else { 未上传 }
             </div>
           </div>

+ 20 - 2
projects/textbook/src/modules/nav-admin/user-edit/user-edit.component.ts

@@ -13,6 +13,8 @@ import { NzMessageService } from 'ng-zorro-antd/message';
 import { textbookServer } from '../../../services/textbook';
 import { NzRadioModule } from 'ng-zorro-antd/radio';
 import Parse from 'parse';
+import { NzImageService } from 'ng-zorro-antd/image';
+import { NzImageModule } from 'ng-zorro-antd/image';
 
 @Component({
   selector: 'app-user-edit',
@@ -28,7 +30,7 @@ import Parse from 'parse';
     NzPopoverModule,
     NzTagModule,
     NzModalModule,
-    NzRadioModule,
+    NzRadioModule,NzImageModule
   ],
   standalone: true,
 })
@@ -61,7 +63,8 @@ export class UserEditComponent implements OnInit {
     public tbookSer: textbookServer,
     private activeRoute: ActivatedRoute,
     private router: Router,
-    private message: NzMessageService
+    private message: NzMessageService,
+    private nzImageService: NzImageService
   ) {}
 
   ngOnInit() {
@@ -236,4 +239,19 @@ export class UserEditComponent implements OnInit {
     this.isShowModal = false;
     this.parent = ''
   }
+  openUrl(url:string){
+    if (!/\.(jpg|jpeg|png|GIF|JPG|PNG)$/.test(url)) {
+      window.open(url);
+    } else {
+      let images = [
+        {
+          src: url,
+          width: '200px',
+          height: '200px',
+          alt: 'ng-zorro'
+        },
+      ]
+      this.nzImageService.preview(images, { nzZoom: 1.5, nzRotate: 0 });
+    }
+  }
 }

+ 16 - 15
projects/textbook/src/modules/nav-author/components/attachment/attachment.component.html

@@ -11,10 +11,10 @@
               版权页截图
             </a>
           }
-          <app-comp-upload [width]="320" (change)="upload($event, 'copyrightImgUrl')" title="上传截图"></app-comp-upload>
+          <app-comp-upload [width]="320" (change)="upload($event, 'copyrightImgUrl')" title="上传PDF"></app-comp-upload>
 
           <div class="text upText" style="margin: 10px 0">
-            支持批量上传 PDF、JPG、JPEG、PNG 格式单个文件大小不超过 2M
+            支持上传PDF,大小不超过 2M
           </div>
         </nz-form-control>
       </nz-form-item>
@@ -28,7 +28,7 @@
               CIP 查询截图
             </a>
           }
-          <app-comp-upload [width]="320" (change)="upload($event, 'CIPImgUrl')" title="上传截图"></app-comp-upload>
+          <app-comp-upload [width]="320" (change)="upload($event, 'CIPImgUrl')" title="上传PDF"></app-comp-upload>
 
           <div class="text upText" style="margin: 10px 0">
             支持批量上传 PDF 格式,单个文件大小不超过 2M。如 CIP 数据中无“教材”字样的,须再上传内容提要或前言或后记中可以证明本书为教材的相关内容截图
@@ -51,9 +51,9 @@
               自查结果记录表
             </a>
           }
-          <app-comp-upload [width]="320" (change)="upload($event, 'selfResults')" title="上传截图"></app-comp-upload>
+          <app-comp-upload [width]="320" (change)="upload($event, 'selfResults')" title="上传PDF"></app-comp-upload>
           <div class="text upText" style="margin: 10px 0">
-            支持批量上传 PDF、JPG、JPEG、PNG 格式单个文件大小不超过 2M
+            支持上传PDF,大小不超过 2M
           </div>
         </nz-form-control>
       </nz-form-item>
@@ -74,7 +74,7 @@
               专家审查意见表
             </a>
           }
-          <app-comp-upload [width]="320" (change)="upload($event, 'expertOpinion')" title="上传截图"></app-comp-upload>
+          <app-comp-upload [width]="320" (change)="upload($event, 'expertOpinion')" title="上传PDF"></app-comp-upload>
           <div class="text upText" style="margin: 10px 0">
             支持批量上传 PDF、JPG、JPEG、PNG 格式,单个大小不超过 2M
           </div>
@@ -84,7 +84,8 @@
     <div class="author-content">
       <div class="title">教材使用情况证明材料</div>
       <div class="text">
-        教材出版单位提供教材主要使用高校名单及使用情况证明材料,并加盖公章。<a (click)="downloadFile('专家审查意见表.docx')">下载模板</a>
+        教材出版单位提供教材主要使用高校名单及使用情况证明材料,并加盖公章。
+        <!-- <a (click)="downloadFile('专家审查意见表.docx')">下载模板</a> -->
       </div>
       <nz-form-item class="row" style="margin-bottom: 16px">
         <nz-form-label class="label" [nzNoColon]="true" [nzSm]="10" [nzXs]="10" nzRequired>教材使用情况证明材料</nz-form-label>
@@ -95,9 +96,9 @@
               证明材料
             </a>
           }
-          <app-comp-upload [width]="320" (change)="upload($event, 'evidence')" title="上传截图"></app-comp-upload>
+          <app-comp-upload [width]="320" (change)="upload($event, 'evidence')" title="上传PDF"></app-comp-upload>
           <div class="text upText" style="margin: 10px 0">
-            支持批量上传 PDF、JPG、JPEG、PNG 格式单个文件大小不超过 2M
+            支持上传PDF,大小不超过 2M
           </div>
         </nz-form-control>
       </nz-form-item>
@@ -115,14 +116,14 @@
           </p>
         }
       }
-      <app-comp-upload [width]="320" [maxlenght]="99" (change)="upload($event, 'moreMaterial')" title="上传截图"></app-comp-upload>
+      <app-comp-upload [width]="320" [maxlenght]="99" (change)="upload($event, 'moreMaterial')" title="上传PDF"></app-comp-upload>
 
       <div class="text upText" style="margin: 10px 0">
-        支持批量上传 PDF、JPG、JPEG、PNG 格式单个文件大小不超过 2M
+        支持上传PDF,大小不超过 2M
       </div>
     </div>
 
-    <div class="author-content">
+    <!-- <div class="author-content">
       <div class="nav"><b>申报单位承诺意见</b></div>
       <div class="text">
         作者 /
@@ -138,13 +139,13 @@
               申报单位承诺意见
             </a>
           }
-          <app-comp-upload [width]="320" (change)="upload($event, 'unitMaterial')" title="上传截图"></app-comp-upload>
+          <app-comp-upload [width]="320" (change)="upload($event, 'unitMaterial')" title="上传PDF"></app-comp-upload>
           <div class="text upText" style="margin: 10px 0">
-            支持批量上传 PDF、JPG、JPEG、PNG 格式单个文件大小不超过 2M
+            支持上传PDF,大小不超过 2M
           </div>
         </nz-form-control>
       </nz-form-item>
-    </div>
+    </div> -->
   <!-- </form> -->
 </div>
 <div class="footer">

+ 7 - 7
projects/textbook/src/modules/nav-author/components/attachment/attachment.component.ts

@@ -143,10 +143,10 @@ export class AttachmentComponent implements OnInit {
         isNull = true
       }
     }
-    if (this.unitMaterial.url == '' || !this.unitMaterial.url) {
-      msgList.push('申报单位承诺意见')
-      isNull = true
-    }
+    // if (this.unitMaterial.url == '' || !this.unitMaterial.url) {
+    //   msgList.push('申报单位承诺意见')
+    //   isNull = true
+    // }
     if (isNull) {
       // this.msg.create('error', `请上传完整 ${msgList.join()}`)
     }
@@ -206,7 +206,7 @@ export class AttachmentComponent implements OnInit {
       expertOpinion: this.expertOpinion,
       evidence: this.evidence,
       moreMaterial: this.moreMaterial,
-      unitMaterial: this.unitMaterial,
+      // unitMaterial: this.unitMaterial,
     }
     await this.saveEduTextbook(params, true);
     if (event == 'pre') {//上一步
@@ -257,8 +257,8 @@ export class AttachmentComponent implements OnInit {
     });
     params.selfResults &&
       this.eduTextbook?.set('selfResults', params.selfResults);
-    params.unitMaterial &&
-      this.eduTextbook?.set('unitMaterial', params.unitMaterial);
+    // params.unitMaterial &&
+    //   this.eduTextbook?.set('unitMaterial', params.unitMaterial);
     params.expertOpinion &&
       this.eduTextbook?.set('expertOpinion', params.expertOpinion);
     params.evidence && this.eduTextbook?.set('evidence', params.evidence);

+ 12 - 3
projects/textbook/src/modules/nav-author/components/basic-in/basic-in.component.html

@@ -183,7 +183,7 @@
       <nz-form-control nzErrorTip="请输入出版时间" [nzSm]="12" [nzXs]="12">
         <nz-input-group>
           <div class="basic-row">
-            <nz-date-picker nzMode="month" style="flex: 1" formControlName="editionDate"></nz-date-picker>
+            <nz-date-picker nzMode="month" style="flex: 1" formControlName="editionDate" [nzDisabledDate]="disabledEditionDate"></nz-date-picker>
             <nz-input-group style="width: 100px; margin-left: 20px" [nzSuffix]="suffixTemplateInfo">
               <input type="number" formControlName="editionNumber" nz-input placeholder="输入版次" />
             </nz-input-group>
@@ -221,7 +221,16 @@
     <nz-form-item style="margin-bottom: 16px">
       <nz-form-label [nzSm]="8" [nzNoColon]="true" [nzXs]="8" nzRequired>初版以来是否列为重点项目</nz-form-label>
       <nz-form-control nzErrorTip="" [nzSm]="12" [nzXs]="12">
-        <nz-input-group>
+        <nz-checkbox-wrapper>
+            @for (item of importantProjectList; track item.value) {
+              <label style="margin: 0;padding: 0;" [ngModelOptions]="{standalone: true}" nz-checkbox [nzValue]="item.value" [(ngModel)]="item.checked">{{item.value}}</label>
+              <br>
+            }
+        </nz-checkbox-wrapper>
+        @if (importantProjectList[4].checked) {
+          <input type="text" formControlName="importantProjectOther" placeholder="请输入入选项目名称" nz-input />
+          }
+        <!-- <nz-input-group>
           <nz-radio-group style="display: flex; flex-direction: column" formControlName="importantProject">
             @for (item of importantProjectList; track item.value) {
             <label (click)="onChangeRadio()" nz-radio [nzValue]="item.value">{{item.title}}</label>
@@ -231,7 +240,7 @@
             }
             <label nz-radio nzValue="否">否</label>
           </nz-radio-group>
-        </nz-input-group>
+        </nz-input-group> -->
       </nz-form-control>
     </nz-form-item>
     <!-- <nz-form-item style="margin-bottom: 16px">

+ 68 - 14
projects/textbook/src/modules/nav-author/components/basic-in/basic-in.component.ts

@@ -19,6 +19,8 @@ import {
 import { CompUploadComponent } from '../../../../app/comp-upload/comp-upload.component';
 import { NzInputModule } from 'ng-zorro-antd/input';
 import * as major from '../../../../services/majors4.map'
+import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
+
 @Component({
   selector: 'app-basic',
   imports: [
@@ -29,7 +31,8 @@ import * as major from '../../../../services/majors4.map'
     NzUploadModule,
     NzInputModule,
     NzTagModule,
-    CompUploadComponent
+    CompUploadComponent,
+    NzCheckboxModule
   ],
   standalone: true,
   templateUrl: './basic-in.component.html',
@@ -71,7 +74,10 @@ export class BasicInComponent implements OnInit {
     
     console.log(result)
   }
-
+  /**出版时间及版次不可选择时间 */
+  disabledEditionDate=(current:Date):boolean=>{
+    return current< new Date(2022,11,1)
+  }
   validateForm: FormGroup<{
     title: FormControl<string>; //申报教材名称
     ISBN: FormControl<string>; //国际标准书号
@@ -97,7 +103,7 @@ export class BasicInComponent implements OnInit {
 
     printSum: FormControl<number>; //初版以来合计印数
 
-    importantProject: FormControl<string>; //初版以来是否列为重点项目
+    // importantProject: FormControl<string>; //初版以来是否列为重点项目
     importantProjectOther: FormControl<string>; //其他省部级及以上项目
     approvedImgUrl:FormControl<string>//重点立项教材获批截图
   
@@ -123,7 +129,7 @@ export class BasicInComponent implements OnInit {
     printDate: [new Date(), [Validators.required]],
     printNumber: [0, [Validators.required]],
     printSum: [0, [Validators.required]],
-    importantProject: ['', [Validators.required]],
+    // importantProject: ['', [Validators.required]],
     importantProjectOther: [''],
     approvedImgUrl:[''],
     // copyrightImgUrl: [''],
@@ -151,30 +157,66 @@ export class BasicInComponent implements OnInit {
       code: 'Z003',
     },
   ];
+  /**可选的重点项目 */
   importantProjectList: Array<any> = [
     {
-      title: '首届全国教材建设奖全国优秀教材(高等教育类)',
+      label: '首届全国教材建设奖全国优秀教材(高等教育类)',
       value: '首届全国教材建设奖全国优秀教材(高等教育类)',
+      checked:false
     },
     {
-      title: '“十二五”普通高等教育本科国家级规划教材',
+      label: '“十二五”普通高等教育本科国家级规划教材',
       value: '“十二五”普通高等教育本科国家级规划教材',
+      checked:false
     },
     {
-      title: '“十二五”以来省级优秀教材',
+      label: '“十二五”以来省级优秀教材',
       value: '“十二五”以来省级优秀教材',
+      checked:false
     },
     {
-      title: '“十二五”以来省级规划教材',
+      label: '“十二五”以来省级规划教材',
       value: '“十二五”以来省级规划教材',
+      checked:false
     },
- 
-    
     {
-      title: '其他省部级及以上项目',
+      label: '其他省部级及以上项目',
       value: '其他省部级及以上项目',
+      checked:false
     },
   ];
+  /**选中的重点项目 */
+  importantProject:Array<any>=[]
+  /**多选框改变 */
+  changeImportantProject(){
+    let checkedList = this.importantProjectList.filter(item=>item.checked)||[]
+    this.importantProject = checkedList.map(item=>item.value)
+    console.log(this.importantProject)
+  }
+  // importantProjectList: Array<any> = [
+  //   {
+  //     title: '首届全国教材建设奖全国优秀教材(高等教育类)',
+  //     value: '首届全国教材建设奖全国优秀教材(高等教育类)',
+  //   },
+  //   {
+  //     title: '“十二五”普通高等教育本科国家级规划教材',
+  //     value: '“十二五”普通高等教育本科国家级规划教材',
+  //   },
+  //   {
+  //     title: '“十二五”以来省级优秀教材',
+  //     value: '“十二五”以来省级优秀教材',
+  //   },
+  //   {
+  //     title: '“十二五”以来省级规划教材',
+  //     value: '“十二五”以来省级规划教材',
+  //   },
+ 
+    
+  //   {
+  //     title: '其他省部级及以上项目',
+  //     value: '其他省部级及以上项目',
+  //   },
+  // ];
   // get importantProjectState(){
   //   return this.importantProjectList.some((item:any)=> item.value == this.validateForm.value.importantProject)
   // }
@@ -191,6 +233,15 @@ export class BasicInComponent implements OnInit {
     if(this.eduTextbook?.get('editionUnit')){
       this.isShowChooseEU=false
     }
+    this.importantProject = this.eduTextbook.get('importantProject')||[]
+    if(this.importantProject?.length>0){
+      for(let i in this.importantProjectList){
+        if(this.importantProject.indexOf(this.importantProjectList[i].value)!=-1){
+          this.importantProjectList[i].checked=true
+        }
+      }
+    }
+ 
     this.approvedImgList[0].url = this.eduTextbook.get('approvedImgUrl')
     console.log(this.approvedImgList)
     console.log(this.eduTextbook);
@@ -215,7 +266,7 @@ export class BasicInComponent implements OnInit {
       printDate: [this.eduTextbook?.get('printDate') || new Date(), [Validators.required]],
       printNumber: [this.eduTextbook?.get('printNumber') || 0, [Validators.required]],
       printSum: [this.eduTextbook?.get('printSum') || 0, [Validators.required]],
-      importantProject: [this.eduTextbook?.get('importantProject') || '', [Validators.required]],
+      // importantProject: [this.eduTextbook?.get('importantProject') || '', [Validators.required]],
       importantProjectOther: [this.eduTextbook?.get('importantProjectOther') || ''],
       approvedImgUrl: [this.eduTextbook?.get('approvedImgUrl') || '', [Validators.required]],
       // copyrightImgUrl: [this.eduTextbook?.get('copyrightImgUrl') || '', [Validators.required]],
@@ -225,7 +276,8 @@ export class BasicInComponent implements OnInit {
   }
   //校验其他省部级及以上项目是否需填
   onChangeRadio(){
-    if (this.validateForm.value.importantProject != '其他省部级及以上项目') {
+    // if (this.validateForm.value.importantProject != '其他省部级及以上项目') {
+    if (!this.importantProjectList[4].checked) {
       this.validateForm.controls.importantProjectOther.clearValidators();
       this.validateForm.controls.importantProjectOther.markAsPristine();
     } else {
@@ -299,6 +351,7 @@ export class BasicInComponent implements OnInit {
   }
 
   async saveEduTextbook(params: any, isComplete:boolean){
+    this.changeImportantProject()
     console.log(params);
     if(!this.eduTextbook){
       let obj = Parse.Object.extend('EduTextbook');
@@ -336,7 +389,8 @@ export class BasicInComponent implements OnInit {
     this.eduTextbook?.set('printDate', params.printDate);
     this.eduTextbook?.set('printNumber', params.printNumber);
     this.eduTextbook?.set('printSum', params.printSum);
-    this.eduTextbook?.set('importantProject', params.importantProject);
+    // this.eduTextbook?.set('importantProject', params.importantProject);
+    this.eduTextbook?.set('importantProject', this.importantProject);
     this.eduTextbook?.set('importantProjectOther', params.importantProjectOther);
     // this.eduTextbook?.set('copyrightImgUrl', params.copyrightImgUrl);
     // this.eduTextbook?.set('CIPImgUrl', params.CIPImgUrl);

+ 7 - 7
projects/textbook/src/modules/nav-author/components/textbook-pertain/textbook-pertain.component.html

@@ -96,14 +96,14 @@
             <th nzWidth="300px">手机号码</th>
             <th nzWidth="160px">电子邮箱</th>
             <th nzWidth="160px">分工</th>
-            <th nzWidth="120px" nzRight>
+            <!-- <th nzWidth="120px" nzRight>
               作者诚信承诺签名
               <span style="color: red;">*</span>
             </th>
             <th nzWidth="120px" nzRight>
               作者政治审查表
               <span style="color: red;">*</span>
-            </th>
+            </th> -->
             <th nzWidth="100px" nzRight>操作</th>
           </tr>
         </thead>
@@ -170,7 +170,7 @@
                 }
               </nz-select>
             </td>
-            <td nzRight>
+            <!-- <td nzRight>
               @if (data.signature) {
                 <a style="color: #3e49b3;" (click)="openFile(data.signature)">签名文件</a>
               }
@@ -181,7 +181,7 @@
               <a style="color: #3e49b3;" (click)="openFile(data.examine)">政治审查表 </a>
               }
               <app-comp-upload (change)="upload($event, 'examine',index)"></app-comp-upload>
-            </td>
+            </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>
@@ -257,11 +257,11 @@
   </form>
   
 </div>
-<div style="width: 100%;display: flex;justify-content: space-between;padding: 30px 0 0;">
-  <a (click)="downloadFile()">
+<div style="width: 100%;display: flex;justify-content: flex-end;padding: 30px 0 0;">
+  <!-- <a (click)="downloadFile()">
     <span nz-icon nzType="download" nzTheme="outline"></span>
     下载本页所有附件模板
-  </a>
+  </a> -->
   <div class="footer">
     <div>
       <button nz-button nzType="default" style="margin-right: 20px" (click)="submitForm('save')">

+ 3 - 2
projects/textbook/src/modules/nav-province-contact/page-role/page-role.component.html

@@ -328,7 +328,7 @@
 
 <nz-modal
   [(nzVisible)]="accountIsVisible"
-  nzTitle="添加账号(手机号及邮箱请至少填写一个,将发送登录账号)"
+  nzTitle="添加账号"
   (nzOnCancel)="handleCancel()"
   nzWidth="800px"
   nzCentered
@@ -424,7 +424,7 @@
           <div class="value">
             <input
               nz-input
-              maxlength="12"
+              maxlength="11"
               placeholder="请输入手机号"
               [(ngModel)]="account.phone"
               type="text"
@@ -475,6 +475,7 @@
       nzType="primary"
       style="background: #3e49b3; border: 1px #3e49b3"
       (click)="accountComplete()"
+      [nzLoading]="isLoadingOne"
     >
       确定
     </button>

+ 39 - 3
projects/textbook/src/modules/nav-province-contact/page-role/page-role.component.ts

@@ -324,7 +324,31 @@ export class PageRoleComponent implements OnInit {
   }
   //删除部门
   onDelDepart() {
-    this.message.warning('权限灰度中');
+    console.log(this.activatedNode);
+    this.modal.confirm({
+      nzTitle: '删除',
+      nzContent: '删除后数据不可恢复,请谨慎操作',
+      nzOkText: '确认',
+      nzOkType: 'primary',
+      nzOkDanger: true,
+      nzOnOk: async () => {
+        new Promise(async (resolve, reject) => {
+          if (this.activatedNode?.key) {
+            let query = new Parse.Query('Department');
+            let r = await query.get(this.activatedNode?.key);
+            if (r?.id) {
+              r.set('isDeleted', true);
+              await r.save();
+            }
+            this.message.success('删除成功');
+            this.nodes = await this.getDepart();
+            resolve(true);
+          }
+        }).catch(() => console.log('Oops errors!'));
+      },
+      nzCancelText: '取消',
+      nzOnCancel: () => console.log('Cancel'),
+    });
   }
 
   onAllChecked(checked: boolean): void {
@@ -531,12 +555,18 @@ export class PageRoleComponent implements OnInit {
     this.account.password = this.tbookSer.randomPassword();
   }
   /* 添加账号 */
+  isLoadingOne:boolean = false
   async accountComplete() {
+    if(this.isLoadingOne) return
+    this.isLoadingOne = true
     this.account.email = this.account?.email.trim();
     this.account.phone = this.account?.phone.trim();
     this.account.name = this.account?.name.trim();
     this.account.password = this.account?.password.trim();
-    if(!this.authVrifly()) return
+    if(!await this.authVrifly()){
+      this.isLoadingOne = false
+      return
+    }
     try {
       let obj = Parse.Object.extend('_User');
       let user = new obj();
@@ -559,6 +589,7 @@ export class PageRoleComponent implements OnInit {
       profile?.set('email', this.account.email);
       profile?.set('identity', this.account.identity);
       let res = await profile?.save();
+      this.isLoadingOne = false
       this.accountIsVisible = false;
       this.account = null;
       this.modal.success({
@@ -570,11 +601,12 @@ export class PageRoleComponent implements OnInit {
       });
     } catch (err: any) {
       console.warn('添加用户错误', err);
+      this.isLoadingOne = false
       this.message.error(err?.Error || '错误:请检查用户邮箱是否已存在');
       return;
     }
   }
-  authVrifly():boolean | undefined{
+  async authVrifly():Promise< boolean | undefined>{
     this.account.email = this.account?.email.trim();
     this.account.phone = this.account?.phone.trim();
     this.account.name = this.account?.name.trim();
@@ -607,6 +639,10 @@ export class PageRoleComponent implements OnInit {
       this.message.error('密码格式错误,请填写6-18位非空字符串(数字、大小写字母或英文符号)');
       return;
     }
+    if(!await this.tbookSer.userFind(this.account.phone)){
+      this.message.error('手机号已存在');
+      return
+    }
     return true
   }
 

+ 5 - 5
projects/textbook/src/modules/nav-province-contact/page-textbook/page-textbook.component.html

@@ -13,7 +13,7 @@
         *nzSpaceItem
         nz-button
         nzType="primary"
-        (click)="toUrl('/nav-province-contact/manage/submitted/' + process?.id)"
+        (click)="submitted()"
       >
       提交推荐教材列表
       </button>
@@ -34,19 +34,19 @@
 <div class="conetent">
   <nz-tabset [(nzSelectedIndex)]="active">
     <nz-tab nzTitle="待评审教材">
-      @if (!active && process) {
+      @if (!active && eduProcess) {
         <app-textbook
-        [eduProcess]="process"
+        [eduProcess]="eduProcess"
         [filterObj]="beforeFilterObj"
       ></app-textbook>
       }
     </nz-tab>
     <nz-tab nzTitle="推荐教材">
-      @if (active && process) {
+      @if (active && eduProcess) {
         <app-textbook
         [filterObj]="afterFilterObj"
         [recommend]="true"
-        [eduProcess]="process"
+        [eduProcess]="eduProcess"
         ></app-textbook>
       }
     </nz-tab>

+ 39 - 2
projects/textbook/src/modules/nav-province-contact/page-textbook/page-textbook.component.ts

@@ -11,6 +11,7 @@ import { TextbookComponent } from '../../../app/textbook/textbook.component';
 import { NzSpaceModule } from 'ng-zorro-antd/space';
 import { CommonCompModule } from '../../../services/common.modules';
 import { NzTabsModule } from 'ng-zorro-antd/tabs';
+import { NzMessageService } from 'ng-zorro-antd/message';
 
 @Component({
   selector: 'app-page-textbook',
@@ -63,10 +64,11 @@ export class PageTextbookComponent implements OnInit {
       export:true
     },
   };
-  process?:Parse.Object
+  eduProcess?:Parse.Object
 
   constructor(
     public tbookSer: textbookServer,
+    private message: NzMessageService,
     private router: Router,
     private activeRoute: ActivatedRoute // private translate:TranslateService,
   ) {
@@ -98,7 +100,7 @@ export class PageTextbookComponent implements OnInit {
     query.notEqualTo('isDeleted', true);
     query.notEqualTo('status', '100');
     let res = await query.first();
-    this.process = res
+    this.eduProcess = res
   }
   toUrl(url: string, params?: object) {
     if (params) {
@@ -107,4 +109,39 @@ export class PageTextbookComponent implements OnInit {
       this.router.navigate([url]);
     }
   }
+  //报送
+  async submitted() {
+    if(this.eduProcess?.get('status') == '400'){
+      this.message.warning('已提交报送,无需重复提交')
+      this.toUrl(`/nav-province-contact/manage/submitted/${this.eduProcess?.id}`)
+      return
+    }
+    this.eduProcess?.set('status', '400');
+    this.eduProcess?.set('releaseDate', new Date());
+    let query = new Parse.Query('EduTextbook');
+    query.equalTo('eduProcess', this.eduProcess?.id);
+    query.notEqualTo('isDeleted', true);
+    query.notEqualTo('discard', true);
+    query.equalTo('render', true);
+    query.equalTo('recommend', true);
+    query.equalTo('status', '200');
+    let list = await query.find();
+    query.containedIn('approval', [
+      '首届全国教材建设奖优秀教材(高等教育类)教材',
+      '否',
+    ]);
+    let count = await query.count();
+    if (count > this.eduProcess?.get('num')) {
+      this.message.warning('当前推荐教材数量已超额')
+      return;
+    }
+    await this.eduProcess?.save();
+    for (let index = 0; index < list.length; index++) {
+      const item = list[index];
+      item.set('status', '400');
+      await item.save();
+    }
+    this.message.success('提交成功')
+    this.toUrl(`/nav-province-contact/manage/submitted/${this.eduProcess?.id}`)
+  }
 }

+ 19 - 4
projects/textbook/src/modules/nav-province-contact/submitted/export-file/export-file.component.html

@@ -1,4 +1,19 @@
-<div class="manage">
+<div class="comple">
+  <div class="title">提交成功</div>
+  <div class="onload" (click)="textbook?.export()">
+    下载推荐汇总表
+  </div>
+</div>
+@if (eduProcess) {
+  <app-textbook
+  [hidden]="true"
+  #textbook
+  [recommend]="true"
+  [filterObj]="filterObj"
+  [eduProcess]="eduProcess"
+></app-textbook>
+}
+<!-- <div class="manage">
   <div class="left">
     <div class="row">
       <div class="lable">推荐教材</div>
@@ -23,9 +38,9 @@
         生成 PDF 并下载
       </button>
   </div>
-</div>
+</div> -->
 
-<div class="footer">
+<!-- <div class="footer">
   <button nz-button nzType="default" (click)="close()" style="margin-right: 20px">取消</button>
   <button nz-button nzType="primary" (click)="next()" style="background: #3e49b3; border: 1px #3e49b3">下一步</button>
-</div>
+</div> -->

+ 23 - 0
projects/textbook/src/modules/nav-province-contact/submitted/export-file/export-file.component.scss

@@ -1,3 +1,26 @@
+.comple{
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  .title{
+    font-family: PingFang SC;
+    font-size: 20px;
+    font-weight: 400;
+    margin-bottom: 20px;
+  }
+  .onload{
+    padding: 10px 20px;
+    background: #f3f3f3;
+    border-radius: 4px;
+    border: 1px solid;
+    cursor: pointer;
+  }
+  .onload:hover{
+    background: #bfbebe;
+  }
+}
 .manage{
   padding: 20px 50px;
   width: 100%;

+ 12 - 2
projects/textbook/src/modules/nav-province-contact/submitted/export-file/export-file.component.ts

@@ -1,22 +1,31 @@
-import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
 import { Router, ActivatedRoute } from '@angular/router';
 import { CommonCompModule } from '../../../../services/common.modules';
+import { TextbookComponent } from '../../../../app/textbook/textbook.component';
 
 import Parse from 'parse';
 @Component({
   selector: 'app-export-file',
   templateUrl: './export-file.component.html',
   styleUrls: ['./export-file.component.scss'],
-  imports: [CommonCompModule],
+  imports: [CommonCompModule,TextbookComponent],
   standalone: true,
 })
 export class ExportFileComponent implements OnInit {
+  @ViewChild('textbook') textbook: ElementRef | any;
   @Output() change: EventEmitter<any> = new EventEmitter<any>();
+  @Input('eduProcess') eduProcess?: Parse.Object;
 
   starCount: number = 0;
   otherCount: number = 0;
   allCount: number = 0;
   tbookId: any;
+  filterObj: any = {
+    isCheck: false,
+    status: ['400'],
+    btns: {},
+  };
+
   constructor(private router: Router, private activeRoute: ActivatedRoute) {}
 
   ngOnInit() {
@@ -51,6 +60,7 @@ export class ExportFileComponent implements OnInit {
       (data) => {
         console.log(data);
         let url = data.zipUrl;
+        url = url.replaceAll("http://","https://");
         const a = document.createElement('a'); // 创建一个&lt;a&gt;元素
         a.href = url; // 设置链接的href属性为要下载的文件的URL
         a.download = '报送流程'; // 设置下载文件的名称

+ 11 - 6
projects/textbook/src/modules/nav-province-contact/submitted/submitted.component.html

@@ -15,20 +15,25 @@
       </div>
     </nz-page-header-title>
   </nz-page-header>
-  <div class="steps">
+  <!-- <div class="steps">
     <nz-steps [nzCurrent]="state">
-      <nz-step nzTitle="导出函报文件" nzDescription=""></nz-step>
+      <nz-step nzTitle="导出推荐汇总表" nzDescription=""></nz-step>
       <nz-step nzTitle="导出公示教材列表" nzDescription=""></nz-step>
       <nz-step nzTitle="完成报送" nzDescription=""></nz-step>
     </nz-steps>
-  </div>
+  </div> -->
 </div>
 
 <div class="content">
-  @switch (state) { @case (0) {
+  @if (eduProcess?.id) {
+    <app-export-file [eduProcess]="eduProcess"></app-export-file>
+  }
+  <!-- @switch (state) { @case (0) {
   <app-export-file (change)="onChange($event)"></app-export-file>
-  } @case (1) {
+  }
+   @case (1) {
   <app-export-list [eduProcess]="eduProcess" (change)="onChange($event)"></app-export-list>
 
-  } @case (2) { <app-complete [eduProcess]="eduProcess"></app-complete>} }
+  } @case (2) { <app-complete [eduProcess]="eduProcess"></app-complete>} 
+  } -->
 </div>

+ 5 - 5
projects/textbook/src/services/auth.service.ts

@@ -16,11 +16,11 @@ export class AuthServr {
   resetcountdown: number = 60; //重置密码验证码倒计时
   redirectUrl: string = '';
   roterPath: any = {
-    国家级管理员: '/nav-admin',
-    工作联系人: '/nav-province-contact',
-    高校联系人: '/nav-province-school-contact',
-    评审专家: '/nav-review',
-    个人: '/nav-author/manage/space',
+    "国家级管理员": '/nav-admin',
+    "工作联系人": '/nav-province-contact',
+    "高校联系人": '/nav-province-school-contact',
+    "评审专家": '/nav-review',
+    "个人": '/nav-author/manage/space',
   };
   constructor(
     public router: Router,

+ 11 - 0
projects/textbook/src/services/textbook.ts

@@ -91,4 +91,15 @@ export class textbookServer {
     }
     return Array.from(new Set([...arr]))
   }
+  userFind(phone:string){
+    return new Promise((res)=>{
+      Parse.Cloud.run('userFind',{mobile:phone}).then(data=>{
+        if(data){
+          res(false)
+        }else{
+          res(true)
+        }
+      }).catch(()=> res(true))
+    })
+  }
 }