Browse Source

管理员创建&编辑流程

warrior 8 months ago
parent
commit
2a2edc5275
26 changed files with 784 additions and 61 deletions
  1. 2 1
      projects/textbook/src/app/comp-manage/comp-manage.component.ts
  2. 17 4
      projects/textbook/src/modules/login/account-info/account-info.component.scss
  3. 50 0
      projects/textbook/src/modules/nav-admin/collection-edit/collection-edit.component.html
  4. 30 0
      projects/textbook/src/modules/nav-admin/collection-edit/collection-edit.component.scss
  5. 24 0
      projects/textbook/src/modules/nav-admin/collection-edit/collection-edit.component.spec.ts
  6. 60 0
      projects/textbook/src/modules/nav-admin/collection-edit/collection-edit.component.ts
  7. 8 0
      projects/textbook/src/modules/nav-admin/components/process/process.component.html
  8. 0 0
      projects/textbook/src/modules/nav-admin/components/process/process.component.scss
  9. 24 0
      projects/textbook/src/modules/nav-admin/components/process/process.component.spec.ts
  10. 37 0
      projects/textbook/src/modules/nav-admin/components/process/process.component.ts
  11. 53 2
      projects/textbook/src/modules/nav-admin/components/profile/profile.component.html
  12. 46 6
      projects/textbook/src/modules/nav-admin/components/profile/profile.component.ts
  13. 97 14
      projects/textbook/src/modules/nav-admin/create-collection/create-collection.component.html
  14. 26 3
      projects/textbook/src/modules/nav-admin/create-collection/create-collection.component.scss
  15. 111 22
      projects/textbook/src/modules/nav-admin/create-collection/create-collection.component.ts
  16. 11 1
      projects/textbook/src/modules/nav-admin/modules.routes.ts
  17. 1 3
      projects/textbook/src/modules/nav-admin/page-collection/page-collection.component.ts
  18. 14 0
      projects/textbook/src/modules/nav-admin/page-textbook/page-textbook.component.html
  19. 0 0
      projects/textbook/src/modules/nav-admin/page-textbook/page-textbook.component.scss
  20. 22 0
      projects/textbook/src/modules/nav-admin/page-textbook/page-textbook.component.spec.ts
  21. 53 0
      projects/textbook/src/modules/nav-admin/page-textbook/page-textbook.component.ts
  22. 6 4
      projects/textbook/src/schemas/EduCollection.ts
  23. 30 0
      projects/textbook/src/schemas/eduProcess.ts
  24. 3 1
      projects/textbook/src/services/common.modules.ts
  25. 2 0
      server/db/index.js
  26. 57 0
      server/db/schemas/EduProcess.js

+ 2 - 1
projects/textbook/src/app/comp-manage/comp-manage.component.ts

@@ -35,7 +35,8 @@ export class CompManageComponent implements OnInit {
             id:'1-1',
           },
           {
-            name:'全部材料',
+            name:'全部教材',
+            path:'/nav-admin/manage/allcollection',
             id:'1-2',
           },
         ]

+ 17 - 4
projects/textbook/src/modules/login/account-info/account-info.component.scss

@@ -20,13 +20,25 @@
   .account-form {
     height: 300px;
     overflow-y: scroll;
-    scrollbar-width: none; /* firefox */
-    -ms-overflow-style: none; /* IE 10+ */
+    // scrollbar-width: none; /* firefox */
+    // -ms-overflow-style: none; /* IE 10+ */
     overflow-x: hidden;
-    overflow-y: auto;
+    
   }
   .account-form::-webkit-scrollbar {
-    display: none; /* Chrome Safari */
+    // display: none; /* Chrome Safari */
+    width: 4px;
+    height: 16px;
+  }
+  .account-form::-webkit-scrollbar-thumb { 
+    border-radius: 10px;
+    -webkit-box-shadow: inset 0 0 5px #b62749;
+    background: #b62749;
+  }
+  .account-form::-webkit-scrollbar-track { //滚动条里面轨道
+    -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);
+    border-radius: 10px;
+    background: #f5f5f5;
   }
 
   nz-form-item {
@@ -35,6 +47,7 @@
     justify-content: start;
     align-items: self-start;
     margin-bottom: 10px;
+    width: calc(100% - 6px);
   }
 }
 .ant-input-group{

+ 50 - 0
projects/textbook/src/modules/nav-admin/collection-edit/collection-edit.component.html

@@ -0,0 +1,50 @@
+<nz-page-header>
+  <nz-breadcrumb nz-page-header-breadcrumb>
+    <nz-breadcrumb-item>国家级管理</nz-breadcrumb-item>
+    <nz-breadcrumb-item><a>报送合集</a></nz-breadcrumb-item>
+  </nz-breadcrumb>
+  <nz-page-header-title
+    >{{eduCollection?.get('name')}}
+    <br />
+    <div class="subtitle">
+      在合集中,你可以创建多个教材推荐报送流程,指定用户为流程管理员,邀请作者、联系人、评审员注册系统,创建并提交教材,由流程管理员提交至合集管理员完成报送
+    </div>
+  </nz-page-header-title>
+  <nz-page-header-extra>
+    <nz-space>
+      <button
+        style="background: #3e49b3; border: 1px #3e49b3"
+        *nzSpaceItem
+        nz-button
+        nzType="primary"
+      >
+      发起报送流程
+      </button>
+    </nz-space>
+  </nz-page-header-extra>
+</nz-page-header>
+<div class="edit-content">
+  <nz-tabset [(nzSelectedIndex)]="active">
+    <nz-tab nzTitle="报送流程">
+      @if (active == 0) {
+      <app-process></app-process>
+      }
+    </nz-tab>
+    <nz-tab nzTitle="合集管理">
+      @if (active == 1) {
+      <app-create-collection [isEdit]="true"></app-create-collection>
+      }
+    </nz-tab>
+    <nz-tab nzTitle="全部教材"> @if (active == 2) {
+      <comp-table-list
+      #list
+      [schema]="EduTextbook"
+      *ngIf="className && fieldsArray"
+      [className]="className"
+      [fieldsArray]="fieldsArray"
+      [queryParams]="queryParams"
+    ></comp-table-list>
+      
+    } </nz-tab>
+  </nz-tabset>
+</div>

+ 30 - 0
projects/textbook/src/modules/nav-admin/collection-edit/collection-edit.component.scss

@@ -0,0 +1,30 @@
+.subtitle{
+  margin-right: 12px;
+  color: #00000073;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1.5715;
+  // overflow: hidden;
+  // white-space: nowrap;
+  // text-overflow: ellipsis;
+}
+.edit-content{
+  margin: 0 0 20px;
+  padding: 0 24px;
+  height: calc(100vh - 250px);
+}
+::ng-deep .ant-page-header-heading-title{
+  white-space: normal;
+}
+::ng-deep .ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn{
+  color: #c6233f;
+}
+::ng-deep .ant-tabs-ink-bar{
+  background: #c6233f;
+}
+::ng-deep .ant-tabs-tab:hover{
+  color: #e97488;
+}
+::ng-deep .ant-tabs-tab-btn:active{
+  color: #e97488;
+}

+ 24 - 0
projects/textbook/src/modules/nav-admin/collection-edit/collection-edit.component.spec.ts

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

+ 60 - 0
projects/textbook/src/modules/nav-admin/collection-edit/collection-edit.component.ts

@@ -0,0 +1,60 @@
+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 { NzTabsModule } from 'ng-zorro-antd/tabs';
+import { ProcessComponent } from '../components/process/process.component';
+import { CreateCollectionComponent } from '../create-collection/create-collection.component';
+import { ActivatedRoute } from '@angular/router';
+import Parse from 'parse';
+import { EduTextbook } from '../../../schemas/EduTextbook';
+import { CompTableListComponent } from '../../../app/comp-table/comp-table-list/comp-table-list.component';
+@Component({
+  selector: 'app-collection-edit',
+  templateUrl: './collection-edit.component.html',
+  styleUrls: ['./collection-edit.component.scss'],
+  imports: [
+    CommonModule,
+    NzSpaceModule,
+    CommonCompModule,
+    NzTabsModule,
+    ProcessComponent,
+    CreateCollectionComponent,
+    CompTableListComponent
+  ],
+  standalone: true,
+})
+export class CollectionEditComponent implements OnInit {
+  active: number = 0;
+  eduCollection: Parse.Object | undefined;
+
+  EduTextbook = EduTextbook;
+  user: Parse.User | undefined;
+  className: string | undefined;
+  queryParams: any | undefined;
+  fieldsArray: Array<any> | undefined;
+
+  constructor(
+    private activeRoute:ActivatedRoute
+  ) {
+    this.user = Parse.User.current();
+    this.className = this.EduTextbook.className;
+    this.fieldsArray = this.EduTextbook.fieldsArray;
+    this.queryParams = {
+      where: {
+        isDeleted: { $ne: true },
+      },
+    };
+  }
+
+  ngOnInit() {
+    this.activeRoute.paramMap.subscribe(async (params) => {
+      let id = params.get('id');
+      if (id) {
+        let query = new Parse.Query('EduCollection');
+        query.equalTo('objectId', id);
+        this.eduCollection = await query.first();
+      }
+    })
+  }
+}

+ 8 - 0
projects/textbook/src/modules/nav-admin/components/process/process.component.html

@@ -0,0 +1,8 @@
+<comp-table-list
+  #list
+  [schema]="EduProcess"
+  *ngIf="className && fieldsArray"
+  [className]="className"
+  [fieldsArray]="fieldsArray"
+  [queryParams]="queryParams"
+></comp-table-list>

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


+ 24 - 0
projects/textbook/src/modules/nav-admin/components/process/process.component.spec.ts

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

+ 37 - 0
projects/textbook/src/modules/nav-admin/components/process/process.component.ts

@@ -0,0 +1,37 @@
+import { Component, OnInit, ViewChild, Input } from '@angular/core';
+import { Router } from '@angular/router';
+import { CompTableListComponent } from '../../../../app/comp-table/comp-table-list/comp-table-list.component';
+import * as Parse from 'parse';
+import { CommonModule } from '@angular/common';
+import { EduProcess } from '../../../../schemas/eduProcess';
+@Component({
+  selector: 'app-process',
+  templateUrl: './process.component.html',
+  styleUrls: ['./process.component.scss'],
+  imports: [CommonModule, CompTableListComponent],
+  standalone: true,
+})
+export class ProcessComponent  implements OnInit {
+
+  @ViewChild(CompTableListComponent) list: CompTableListComponent | undefined;
+
+  EduProcess = EduProcess;
+  user: Parse.User | undefined;
+  className: string | undefined;
+  queryParams: any | undefined;
+  fieldsArray: Array<any> | undefined;
+
+  constructor() { 
+    this.user = Parse.User.current();
+    this.className = this.EduProcess.className;
+    this.fieldsArray = this.EduProcess.fieldsArray;
+    this.queryParams = {
+      where: {
+        isDeleted: { $ne: true },
+      },
+    };
+  }
+
+  ngOnInit() {}
+
+}

+ 53 - 2
projects/textbook/src/modules/nav-admin/components/profile/profile.component.html

@@ -1,8 +1,59 @@
-<comp-table-list
+<!-- <comp-table-list
   #list
   [schema]="Profile"
   *ngIf="className && fieldsArray"
   [className]="className"
   [fieldsArray]="fieldsArray"
   [queryParams]="queryParams"
-></comp-table-list>
+></comp-table-list> -->
+<nz-table
+  #basicTable
+  [nzData]="profiles"
+  [nzScroll]="{ x: (maxWidth || '800') + 'px', y: '480px' }"
+  [nzTotal]="profiles.length"
+  [nzPageSize]="10"
+  style="margin: 10px 0"
+>
+  <thead>
+    <tr>
+      <th nzWidth="120px" nzLeft>姓名</th>
+      <th nzWidth="120px">电话号码</th>
+      <th nzWidth="120px">邮箱</th>
+      <th nzWidth="120px">注册时间</th>
+      <th nzWidth="120px">是否填报人</th>
+      @if (!disabled) {
+      <th nzWidth="120px" nzRight>操作</th>
+      }
+    </tr>
+  </thead>
+  <tbody>
+    @for (data of profiles; track data.id) {
+    <tr>
+      <td nzLeft>
+        {{ data?.get("name") }}
+      </td>
+      <td>
+        {{ data?.get("mobile") }}
+      </td>
+      <td>
+        {{ data?.get("email") }}
+      </td>
+      <td>
+        {{ data?.createdAt | date : "yyyy-MM-dd" }}
+      </td>
+      <td>
+        <nz-switch [ngModel]="checked(data.id)" nzDisabled></nz-switch>
+      </td>
+      @if (!disabled) {
+      <td nzRight>
+        @if(checked(data.id)){
+        <a (click)="onChange(data.id)" style="color: #c6233f">取消权限</a>
+        }@else {
+        <a (click)="onChange(data.id)">设置权限</a>
+        }
+      </td>
+      }
+    </tr>
+    }
+  </tbody>
+</nz-table>

+ 46 - 6
projects/textbook/src/modules/nav-admin/components/profile/profile.component.ts

@@ -1,17 +1,30 @@
-import { Component, OnInit, ViewChild, Input } from '@angular/core';
+import { Component, OnInit, ViewChild, Input, Output, EventEmitter } from '@angular/core';
+import { CommonCompModule } from '../../../../services/common.modules';
 import { ActivatedRoute, RouterOutlet, Router } from '@angular/router';
 import { CompTableListComponent } from '../../../../app/comp-table/comp-table-list/comp-table-list.component';
 import { Profile } from '../../../../schemas/Profile';
 import * as Parse from 'parse';
 import { CommonModule } from '@angular/common';
+import { NzMessageService } from 'ng-zorro-antd/message';
 @Component({
   selector: 'app-profile',
   templateUrl: './profile.component.html',
   styleUrls: ['./profile.component.scss'],
-  imports: [CommonModule, RouterOutlet, CompTableListComponent],
+  imports: [CommonModule, RouterOutlet, CompTableListComponent, CommonCompModule],
   standalone: true,
 })
 export class ProfileComponent  implements OnInit {
+  @Input('maxWidth') maxWidth:any //最大宽度
+  @Input('maxChecked') maxChecked:number = 1 //最大可操作数量
+  @Input('idList') idList:Array<string> = [] //已指向id
+  @Input('identity') identity:any //指定身份类型
+  @Input('province') province:any //指定省份
+  @Input('disabled') disabled:boolean = false //禁止编辑
+
+  @Output() change: EventEmitter<any> = new EventEmitter<any>();
+
+  profiles:Array<Parse.Object> = []
+  
   @ViewChild(CompTableListComponent) list: CompTableListComponent | undefined;
 
   Profile = Profile;
@@ -19,8 +32,13 @@ export class ProfileComponent  implements OnInit {
   className: string | undefined;
   queryParams: any | undefined;
   fieldsArray: Array<any> | undefined;
-
-  constructor() { 
+  //是否存在已选中
+  checked(id:string):boolean{
+    return this.idList.some((item:string)=> item == id)
+  }
+  constructor(
+    private msg: NzMessageService,
+  ) { 
     this.user = Parse.User.current();
     this.className = this.Profile.className;
     this.fieldsArray = this.Profile.fieldsArray;
@@ -31,6 +49,28 @@ export class ProfileComponent  implements OnInit {
     };
   }
 
-  ngOnInit() {}
-
+  ngOnInit() {
+    this.getProfile()
+  }
+  async getProfile(){
+    let query = new Parse.Query('Profile')
+    this.identity && query.equalTo('identity',this.identity)
+    this.province && query.equalTo('province',this.province)
+    this.disabled && query.equalTo('objectId',this.idList[0])
+    this.profiles = await query.find()
+  }
+  onChange(id:string){
+    console.log(this.idList);
+    let index = this.idList.findIndex(item=> item == id)
+    if(index == -1){
+      if(this.idList.length >= this.maxChecked){
+        this.msg.warning('超出数量限制')
+        return
+      }
+      this.idList.push(id)
+    }else{
+      this.idList.splice(index,1)
+    }
+    this.change.emit(this.idList)
+  }
 }

+ 97 - 14
projects/textbook/src/modules/nav-admin/create-collection/create-collection.component.html

@@ -1,16 +1,18 @@
 <!-- 表格头部 -->
-<nz-page-header nzTitle="创建新合集">
-  <nz-breadcrumb nz-page-header-breadcrumb>
-    <nz-breadcrumb-item>创建合集</nz-breadcrumb-item>
-    <nz-breadcrumb-item><a>报送合集</a></nz-breadcrumb-item>
-  </nz-breadcrumb>
-</nz-page-header>
-<div class="content">
+@if (!isEdit) {
+  <nz-page-header nzTitle="创建新合集">
+    <nz-breadcrumb nz-page-header-breadcrumb>
+      <nz-breadcrumb-item>创建合集</nz-breadcrumb-item>
+      <nz-breadcrumb-item><a>报送合集</a></nz-breadcrumb-item>
+    </nz-breadcrumb>
+  </nz-page-header>
+}
+<div class="content" [style.padding]="isEdit ? '0' : '0 24px 16px'">
   <form
     nz-form
     [formGroup]="validateForm"
     class="login-form"
-    (ngSubmit)="submitForm()"
+    (ngSubmit)="submitForm('save')"
   >
     <div class="title">基本信息</div>
     <div class="fill-template">
@@ -106,6 +108,36 @@
           </nz-form-item>
         </div>
         <div nz-col nzSpan="12">
+          @if (isEdit) {
+          <nz-form-item class="row" style="margin-bottom: 16px">
+            <nz-form-label
+              class="label"
+              [nzNoColon]="true"
+              [nzSm]="18"
+              [nzXs]="18"
+              nzRequired
+              >流程数量</nz-form-label
+            >
+            <nz-form-control
+              class="val"
+              nzErrorTip="请填写流程数量"
+              style="width: 100%"
+            >
+              <nz-input-group
+                [nzAddOnAfter]="getNumlength() + '/' + 50"
+              >
+                <input
+                  nz-input
+                  type="number"
+                  placeholder="请填写流程数量"
+                  formControlName="num"
+                  nzStatus=""
+                  maxlength="50"
+                />
+              </nz-input-group>
+            </nz-form-control>
+          </nz-form-item>
+          }@else {
           <nz-form-item class="row" style="margin-bottom: 16px">
             <nz-form-label
               class="label"
@@ -135,6 +167,7 @@
               </nz-select>
             </nz-form-control>
           </nz-form-item>
+          }
         </div>
       </div>
       <div nz-row>
@@ -146,13 +179,63 @@
                 报送人可查看合集中所有流程报送的教材、报送配额、用户,可创建所属省份与自己相同的账号、用户组;可公示和报送合集中所有教材。
               </div>
             </div>
-            <a class="btn">选择报送人</a>
+            <a class="btn" (click)="onShowCheck()">{{
+              eduCollection?.get("profileSubmitted")?.id
+                ? "修改报送人"
+                : "选择报送人"
+            }}</a>
+          </div>
+          <div class="tabs" #maxWidth>
+            @if (eduCollection?.get('profileSubmitted') && !showProfileFrom) {
+            <app-profile
+              [idList]="profileId ? [profileId] : []"
+              (change)="changeSubmitted($event)"
+              [maxWidth]="maxWidth"
+              [disabled]="true"
+            ></app-profile>
+            } @else if(showProfileFrom){
+            <app-profile
+              [idList]="profileId ? [profileId] : []"
+              [maxWidth]="maxWidth"
+              (change)="changeSubmitted($event)"
+            ></app-profile>
+            }
           </div>
-          <div class="tabs">
-            @if (!showEdit) {
-            <app-profile></app-profile>
-            } @else{
-            <app-submitted></app-submitted>
+          <div class="fonter">
+            @if (!eduCollection?.id) {
+            <button
+              class="form-button"
+              type="button"
+              mat-raised-button
+              (click)="submitForm('save')"
+            >
+              创建
+            </button>
+            <button
+              class="form-button close"
+              type="button"
+              mat-raised-button
+              (click)="submitForm('close')"
+            >
+              取消
+            </button>
+            } @else {
+            <button
+              class="form-button"
+              type="button"
+              mat-raised-button
+              (click)="submitForm('save')"
+            >
+              保存
+            </button>
+            <button
+              class="form-button close"
+              type="button"
+              mat-raised-button
+              (click)="submitForm('close')"
+            >
+              取消
+            </button>
             }
           </div>
         </div>

+ 26 - 3
projects/textbook/src/modules/nav-admin/create-collection/create-collection.component.scss

@@ -38,13 +38,36 @@
     .btn {
       margin-left: 20px;
       flex-shrink: 0;
-      color: #006DED;
+      color: #006ded;
     }
   }
+
 }
-::ng-deep .ant-page-header {
-  padding: 16px 24px 0;
+.fonter{
+  text-align: right;
+  .form-button {
+    width: 80px;
+    height: 40px;
+    margin: 20px 0;
+    color: white !important;
+    background-color: #3E49B3!important;
+    border-radius: 4px;
+    font-family: PingFang SC;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 20px;
+    text-align: center;
+  }
+  .close{
+    background-color: #eae6e6 !important;
+    color: black !important;
+    margin-left: 20px;
+  }
 }
+
+// ::ng-deep .ant-page-header {
+//   padding: 16px 24px 0;
+// }
 ::ng-deep .ant-page-header-heading-title {
   color: black;
 }

+ 111 - 22
projects/textbook/src/modules/nav-admin/create-collection/create-collection.component.ts

@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, Input, OnInit } from '@angular/core';
 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 import { CommonCompModule } from '../../../services/common.modules';
 import { Router, ActivatedRoute } from '@angular/router';
@@ -14,33 +14,46 @@ import { textbookServer } from '../../../services/textbook';
 import { NzMessageService } from 'ng-zorro-antd/message';
 import { NzModalService } from 'ng-zorro-antd/modal';
 import { provinces } from '../../../services/provinces';
-import { SubmittedComponent } from '../components/submitted/submitted.component'
-import { ProfileComponent } from '../components/profile/profile.component'
+import { SubmittedComponent } from '../components/submitted/submitted.component';
+import { ProfileComponent } from '../components/profile/profile.component';
+import { MatButtonModule } from '@angular/material/button';
 @Component({
   selector: 'app-create-collection',
   imports: [
-    CommonCompModule,FormsModule, ReactiveFormsModule,NzSelectModule,SubmittedComponent,ProfileComponent
+    CommonCompModule,
+    FormsModule,
+    ReactiveFormsModule,
+    NzSelectModule,
+    SubmittedComponent,
+    ProfileComponent,
+    MatButtonModule
   ],
   standalone: true,
   templateUrl: './create-collection.component.html',
   styleUrls: ['./create-collection.component.scss'],
 })
-export class CreateCollectionComponent  implements OnInit {
-  eduCollection:Parse.Object|undefined
-  provinces: Array<string> = provinces.options
-  showEdit:boolean = false
-
+export class CreateCollectionComponent implements OnInit {
+  eduCollection: Parse.Object | undefined;
+  provinces: Array<string> = provinces.options;
+  showProfileFrom: boolean = false;
+  @Input('isEdit')isEdit:boolean = false //当前是否作为编辑子组件
+  profileId:string = '' //报送人
   validateForm: FormGroup<{
     name: FormControl<Array<string> | any>; //合集名称
     desc: FormControl<Array<string> | any>; //合集描述
     code: FormControl<string | any>; //合集code
-    area:FormControl<string>; //关联省级行政区
+    area: FormControl<string>; //关联省级行政区
+    num: FormControl<number|any>; //流程数量
   }> = this.fb.group({
     name: ['', [Validators.required]],
     desc: ['', [Validators.required]],
     code: ['', [Validators.required]],
     area: ['', [Validators.required]],
-  })
+    num: [''],
+  });
+  getNumlength():number{
+    return this.validateForm.value.num.toString().length
+  }
   constructor(
     private activeRoute: ActivatedRoute,
     private router: Router,
@@ -48,30 +61,71 @@ export class CreateCollectionComponent  implements OnInit {
     private fb: NonNullableFormBuilder,
     private msg: NzMessageService,
     private modal: NzModalService
-  ) { }
+  ) {}
 
   ngOnInit() {
     this.activeRoute.paramMap.subscribe(async (params) => {
       let id = params.get('id');
+      console.log(id);
       if (id) {
+        this.isEdit = true
         let query = new Parse.Query('EduCollection');
         query.equalTo('objectId', id);
-        this.eduCollection = await query.first()
+        this.eduCollection = await query.first();
+        this.validateForm = this.fb.group({
+          name: [
+            this.eduCollection?.get('name') || '',
+            [Validators.required],
+          ],
+          desc: [
+            this.eduCollection?.get('desc') || '',
+            [Validators.required],
+          ],
+          code: [
+            this.eduCollection?.get('code') || '',
+            [Validators.required],
+          ],
+          area: [
+            this.eduCollection?.get('area') || '',
+            [Validators.required],
+          ],
+          num: [
+            this.eduCollection?.get('num') || '',
+            [Validators.required],
+          ],
+        });
+        this.profileId = this.eduCollection?.get('profileSubmitted')?.id
       }
-      this.validateForm = this.fb.group({
-        name: [this.eduCollection?.get('this.eduCollection') ||'', [Validators.required]],
-        desc: [this.eduCollection?.get('this.desc') ||'', [Validators.required]],
-        code: [this.eduCollection?.get('this.code') ||'', [Validators.required]],
-        area: [this.eduCollection?.get('this.area') ||'', [Validators.required]],
-      })
     });
   }
-
-  submitForm(): void {
+  onShowCheck(){
+    if(!this.eduCollection?.id){
+      this.msg.warning('请先创建合集')
+      return
+    }
+    this.showProfileFrom = true
+  }
+  async submitForm(type:string):Promise<void> {
+    if(type == 'close'){
+      this.modal.confirm({
+        nzTitle: '你确定取消吗?',
+        nzContent: '',
+        nzOkText: '是',
+        nzOkType: 'primary',
+        nzOkDanger: true,
+        nzOnOk: () => history.back(),
+        nzCancelText: '否',
+        nzOnCancel: () => console.log('Cancel')
+      });
+      return
+    }
     if (this.validateForm.valid) {
       console.log('submit', this.validateForm.value);
+      let params = this.validateForm.value
+      this.saveEduCollection(params)
     } else {
-      Object.values(this.validateForm.controls).forEach(control => {
+      this.msg.warning('请填写完整信息')
+      Object.values(this.validateForm.controls).forEach((control) => {
         if (control.invalid) {
           control.markAsDirty();
           control.updateValueAndValidity({ onlySelf: true });
@@ -79,4 +133,39 @@ export class CreateCollectionComponent  implements OnInit {
       });
     }
   }
+
+  async saveEduCollection(params:any){
+    if(!this.eduCollection?.id){
+      let obj = Parse.Object.extend('EduCollection');
+      this.eduCollection = new obj();
+    }
+    this.eduCollection?.set('user', Parse.User.current()?.toPointer());
+    this.eduCollection?.set('company', {
+      __type: 'Pointer',
+      className: 'Company',
+      objectId: this.tbookSer.company,
+    });
+    this.eduCollection?.set('name', params.name);
+    this.eduCollection?.set('desc', params.desc);
+    this.eduCollection?.set('code', params.code);
+    if(this.isEdit){
+      this.eduCollection?.set('num', params.num);
+    }else{
+      this.eduCollection?.set('area', params.area);
+    }
+    this.profileId ? this.eduCollection?.set('profileSubmitted',{
+      __type: 'Pointer',
+      className: 'Profile',
+      objectId: this.profileId,
+    }) :
+    this.eduCollection?.set('profileSubmitted',undefined)
+    this.eduCollection = await this.eduCollection?.save()
+    this.msg.success(this.isEdit ? '已保存' : '已创建')
+    this.showProfileFrom = false
+  }
+
+  async changeSubmitted(e:Array<string>){
+    console.log(e);
+    if(e[0]) this.profileId = e[0]
+  }
 }

+ 11 - 1
projects/textbook/src/modules/nav-admin/modules.routes.ts

@@ -1,8 +1,10 @@
 import { NgModule } from '@angular/core';
 import { RouterModule, Routes } from '@angular/router';
+import { CollectionEditComponent } from './collection-edit/collection-edit.component';
 import { CreateCollectionComponent } from './create-collection/create-collection.component';
 import { PageCollectionComponent } from './page-collection/page-collection.component';
 import { PageRoleComponent } from './page-role/page-role.component';
+import { PageTextbookComponent } from './page-textbook/page-textbook.component';
 import { PageUserComponent } from './page-user/page-user.component';
 const routes: Routes = [
   {
@@ -18,9 +20,17 @@ const routes: Routes = [
         component: PageCollectionComponent,
       },
       {
-        path: 'create/collection', //合集列表
+        path: 'collection/create', //创建&管理合集
         component: CreateCollectionComponent,
       },
+      {
+        path: 'collection/edit', //合集编辑
+        component: CollectionEditComponent,
+      },
+      {
+        path: 'allcollection', //合集列表
+        component: PageTextbookComponent,
+      },
       {
         path: 'user', //用户列表
         component: PageUserComponent,

+ 1 - 3
projects/textbook/src/modules/nav-admin/page-collection/page-collection.component.ts

@@ -12,8 +12,6 @@ import { NzPageHeaderModule } from 'ng-zorro-antd/page-header';
 import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb';
 import { NzSpaceModule } from 'ng-zorro-antd/space';
 import { NzDropDownModule } from 'ng-zorro-antd/dropdown';
-
-
 @Component({
   selector: 'app-page-collection',
   templateUrl: './page-collection.component.html',
@@ -58,6 +56,6 @@ export class PageCollectionComponent  implements OnInit {
     });
   }
   create(){
-    this.router.navigate(['/nav-admin/manage/create/collection'])
+    this.router.navigate(['/nav-admin/manage/collection/create'])
   }
 }

+ 14 - 0
projects/textbook/src/modules/nav-admin/page-textbook/page-textbook.component.html

@@ -0,0 +1,14 @@
+<nz-page-header>
+  <nz-breadcrumb nz-page-header-breadcrumb>
+    <nz-breadcrumb-item>国家级管理</nz-breadcrumb-item>
+    <nz-breadcrumb-item><a>报送合集</a></nz-breadcrumb-item>
+  </nz-breadcrumb>
+</nz-page-header>
+<comp-table-list
+  #list
+  [schema]="EduTextbook"
+  *ngIf="className && fieldsArray"
+  [className]="className"
+  [fieldsArray]="fieldsArray"
+  [queryParams]="queryParams"
+></comp-table-list>

+ 0 - 0
projects/textbook/src/modules/nav-admin/page-textbook/page-textbook.component.scss


+ 22 - 0
projects/textbook/src/modules/nav-admin/page-textbook/page-textbook.component.spec.ts

@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+
+import { PageTextbookComponent } from './page-textbook.component';
+
+describe('PageTextbookComponent', () => {
+  let component: PageTextbookComponent;
+  let fixture: ComponentFixture<PageTextbookComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [PageTextbookComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(PageTextbookComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 53 - 0
projects/textbook/src/modules/nav-admin/page-textbook/page-textbook.component.ts

@@ -0,0 +1,53 @@
+import { Component, OnInit, ViewChild, Input } from '@angular/core';
+import { ActivatedRoute, RouterOutlet, Router } from '@angular/router';
+import { CompTableListComponent } from '../../../app/comp-table/comp-table-list/comp-table-list.component';
+import { EduTextbook } from '../../../schemas/EduTextbook';
+import { NzPageHeaderModule } from 'ng-zorro-antd/page-header';
+import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb';
+import * as Parse from 'parse';
+import { CommonModule } from '@angular/common';
+@Component({
+  selector: 'app-page-textbook',
+  templateUrl: './page-textbook.component.html',
+  styleUrls: ['./page-textbook.component.scss'],
+  imports: [CommonModule, RouterOutlet, CompTableListComponent,NzPageHeaderModule,NzBreadCrumbModule],
+  standalone: true,
+})
+export class PageTextbookComponent implements OnInit {
+  @ViewChild(CompTableListComponent) list: CompTableListComponent | undefined;
+  @Input('discard') discard: boolean = false;
+  @Input('render') render: boolean = false;
+
+  EduTextbook = EduTextbook;
+  user: Parse.User | undefined;
+  className: string | undefined;
+  queryParams: any | undefined;
+  fieldsArray: Array<any> | undefined;
+
+  constructor(
+    private router: Router,
+    private activeRoute: ActivatedRoute
+  ) // private translate:TranslateService,
+  {
+    this.user = Parse.User.current();
+    this.className = this.EduTextbook.className;
+    this.fieldsArray = this.EduTextbook.fieldsArray;
+    this.queryParams = {
+      where: {
+        isDeleted: { $ne: true },
+        discard: this.discard ? { $eq: true } : { $ne: true },
+        render: this.render ? { $eq: true } : { $ne: true },
+      },
+    };
+  }
+
+  ngOnInit(): void {
+    console.log(this.discard);
+    console.log(this.render);
+    this.queryParams.where = {
+      isDeleted: { $ne: true },
+      discard: this.discard ? { $eq: true } : { $ne: true },
+      render: this.render ? { $eq: true } : { $ne: true },
+    };
+  }
+}

+ 6 - 4
projects/textbook/src/schemas/EduCollection.ts

@@ -1,4 +1,5 @@
 import { MatDialog } from "@angular/material/dialog";
+import { Router } from "@angular/router";
 import { openObjectEditDialog, ParseSchema } from "./func-parse";
 
 
@@ -10,13 +11,13 @@ const EduCollection:ParseSchema = {
     emptyDesc:"请您创建报送合集,分配合集管理员,统一管理各地区的教材推荐报送流程和配额。",
     "fieldsArray": [
         {
-            "key":"title",
+            "key":"name",
             "name":"合集名称",
             "type": "String",
             isHeader:true
         },
         {
-            "key":"name",
+            "key":"code",
             "name":"合集CODE",
             "type": "String",
             isHeader:true
@@ -53,8 +54,9 @@ const EduCollection:ParseSchema = {
             show:(options:{object:Parse.Object})=>{
                 return true
             },
-            handle:(options:{dialog:MatDialog,object:Parse.Object})=>{
-                openObjectEditDialog(options?.dialog,EduCollection,options?.object)
+            handle:(options:{dialog:MatDialog,object:Parse.Object,router:Router})=>{
+                // openObjectEditDialog(options?.dialog,EduCollection,options?.object)
+                options.router.navigate(['/nav-admin/manage/collection/edit',{id:options.object.id}])
             }
         },
     ]

+ 30 - 0
projects/textbook/src/schemas/eduProcess.ts

@@ -0,0 +1,30 @@
+import { MatDialog } from "@angular/material/dialog";
+import { Router } from "@angular/router";
+import Parse from "parse";
+import { ParseSchema } from "./func-parse";
+
+export const EduProcess:ParseSchema = {
+    title:"报送流程",
+    className:"EduProcess",
+    emptyImg:"/img/webhook-empty.png",
+    include:["eduCollection"],
+    buttons:[
+        {
+            name:"编辑",
+            place:"item",
+            show:(options:{object:Parse.Object})=>{
+                if(location?.pathname=='/nav-author/manage/space'){
+                    return true
+                }
+                return false
+            },
+            handle:(options:{dialog:MatDialog,object:Parse.Object,router?:Router})=>{
+                options.router?.navigate(['/nav-author/manage/apply',{id:options.object.id}])
+            }
+        }
+    ],
+    fieldsArray:[
+        {key:"eduCollection",name:"所属合集",type:"Pointer",targetClass:"EduCollection",isHeader:true,showName:"${name}"},
+        {key:"name",name:"流程名称",type:"String",isHeader:true},
+    ]
+}

+ 3 - 1
projects/textbook/src/services/common.modules.ts

@@ -13,6 +13,7 @@ import { NzButtonModule } from 'ng-zorro-antd/button';
 import { NzInputModule } from 'ng-zorro-antd/input';
 import { NzDatePickerModule } from 'ng-zorro-antd/date-picker';
 import { NzModalModule } from 'ng-zorro-antd/modal';
+import { NzSwitchModule } from 'ng-zorro-antd/switch';
 @NgModule({
   exports: [
     FormsModule,
@@ -28,7 +29,8 @@ import { NzModalModule } from 'ng-zorro-antd/modal';
     NzButtonModule,
     NzInputModule,
     NzDatePickerModule,
-    NzModalModule
+    NzModalModule,
+    NzSwitchModule
   ]
 })
 export class CommonCompModule { }

+ 2 - 0
server/db/index.js

@@ -6,6 +6,7 @@ import {_User} from "./schemas/_User"
 import {_Role} from "./schemas/_Role"
 import {_Session} from "./schemas/_Session"
 import {Submitted} from "./schemas/Submitted"
+import {EduProcess} from "./schemas/EduProcess"
 
 export const EduSchemas = [
     _User,
@@ -16,5 +17,6 @@ export const EduSchemas = [
     Profile,
     EduCollection,
     Submitted,
+    EduProcess
 ]
 module.exports.EduSchemas = EduSchemas

+ 57 - 0
server/db/schemas/EduProcess.js

@@ -0,0 +1,57 @@
+export const EduProcess = {
+  "className": "EduProcess",
+  "fields": {
+    "eduCollection": { //指向报送合集
+      "type": "Pointer",
+      "targetClass": "EduCollection",
+      "required": false
+    },
+    "name": {//流程名称
+      "type": "String",
+      "required": false
+    },
+    "num": {//报送名额
+      "type": "Number",
+      "required": false
+    },
+    "startDate": {//开始时间
+      "type": "Date",
+      "required": false
+    },
+    "deadline": {//截止时间
+      "type": "Date",
+      "required": false
+    },
+    "status": {//状态
+      "type": "Date",
+      "required": false
+    },
+  },
+  "classLevelPermissions": {
+    "find": {
+      "*": true
+    },
+    "get": {
+      "*": true
+    },
+    "count": {
+      "*": true
+    },
+    "create": {
+      "*": true
+    },
+    "update": {
+      "*": true
+    },
+    "delete": {
+      "*": true
+    },
+    "addField": {
+      "*": true
+    },
+    "protectedFields": {
+      "*": []
+    }
+  }
+}
+module.exports.EduProcess = EduProcess