warrior 8 months ago
parent
commit
77913e5672

+ 6 - 4
projects/textbook/src/modules/nav-admin/page-process/process-create/process-create.component.ts

@@ -236,10 +236,12 @@ export class ProcessCreateComponent implements OnInit {
       query.equalTo('objectId', id);
       query.select('parent', 'name');
       let r = await query.first();
-      arr.push({
-        title: r?.get('name'),
-        id: r?.id,
-      });
+      if(!r?.get('parent')){
+        arr.push({
+          title: r?.get('name'),
+          id: r?.id,
+        });
+      }
       arr.unshift(...(await this.formatNode(r?.get('parent')?.id)));
     }
     return arr;

+ 57 - 27
projects/textbook/src/modules/nav-admin/page-process/process-list/process-list.component.html

@@ -104,17 +104,21 @@
       <nz-table
         #tableData
         [nzData]="eduProcessList"
-        [nzTotal]="eduProcessList.length"
-        [nzPageSize]="10"
+        [nzTotal]="eduProcessLength"
+        [nzPageSize]="pageSize"
+        [nzPageIndex]="pageIndex"
         style="margin: 10px 0"
         [nzLoading]="loading"
         nzSize="middle"
         [nzNoResult]="emptyResult"
         nzTableLayout="fixed"
+        [nzFrontPagination]="false"
+        (nzPageIndexChange)="pageIndexChange($event)"
       >
         <thead>
           <tr>
-            <th nzEllipsis
+            <th
+              nzEllipsis
               nzWidth="50px"
               nzLeft
               [nzChecked]="checkedAll"
@@ -122,7 +126,7 @@
               nzLabel="Select all"
               (nzCheckedChange)="onAllChecked($event)"
             ></th>
-            <th nzEllipsis nzWidth="120px" nzLeft>流程名称</th>
+            <th nzWidth="120px" nzLeft>流程名称</th>
             <th nzEllipsis nzWidth="120px">流程code</th>
             <th nzEllipsis nzWidth="120px">流程描述</th>
             <th nzEllipsis nzWidth="80px">申报限额</th>
@@ -132,39 +136,42 @@
           </tr>
         </thead>
         <tbody>
-          @for (data of eduProcessList; track data.objectId) {
+          @for (data of tableData.data; track data.id) {
           <tr>
-            <td nzEllipsis
+            <td
+              nzEllipsis
               nzLeft
-              [nzChecked]="data.checked"
-              (nzCheckedChange)="onItemChecked(data.objectId, $event)"
+              [nzChecked]="setOfCheckedId.has(data.id)"
+              (nzCheckedChange)="onItemChecked(data.id, $event)"
             ></td>
-            <td nzEllipsis
-              nzLeft
+            <td
+              nzEllipsis
               (click)="
                 toUrl('/nav-admin/manage/process/page', {
-                  id: data?.objectId
+                  id: data?.id
                 })
               "
               class="activeTd"
             >
-              {{ data?.name || "-" }}
+              {{ data?.get("name") || "-" }}
             </td>
             <td nzEllipsis>
-              {{ data?.code || "-" }}
+              {{ data?.get("code") || "-" }}
             </td>
             <td nzEllipsis>
-              {{ data?.desc || "-" }}
+              {{ data?.get("desc") || "-" }}
             </td>
             <td nzEllipsis>
-              {{ data?.num || "-" }}
+              {{ data?.get("num ") || "-" }}
             </td>
             <td nzEllipsis>
-              {{ data?.profileSubmitted?.user.name || "-" }}
+              {{
+                data?.get("profileSubmitted")?.get("user").get("name") || "-"
+              }}
             </td>
             <td nzEllipsis>
-              <nz-tag [nzColor]="data?.state.color">
-                {{ data?.state.title }}</nz-tag
+              <nz-tag [nzColor]="statusMap[data.id].color">
+                {{ statusMap[data.id].title }}</nz-tag
               >
             </td>
             <td nzEllipsis nzRight>
@@ -178,13 +185,13 @@
               </button>
               <nz-dropdown-menu #menu="nzDropdownMenu">
                 <ul nz-menu>
-                  @if (data.state?.strat){
+                  @if (statusMap[data.id].strat){
                   <li nz-menu-item>
                     <button
                       nz-button
-                      [disabled]="user?.get('isDeleted')"
                       nzType="link"
                       style="color: #231c1f"
+                      (click)="onStatusChange(data, 'strat', true)"
                     >
                       <span
                         nz-icon
@@ -194,13 +201,13 @@
                       >开始流程
                     </button>
                   </li>
-                  } @if (data.state?.stop){
+                  } @if (statusMap[data.id].stop){
                   <li nz-menu-item>
                     <button
                       nz-button
-                      [disabled]="user?.get('isDeleted')"
                       nzType="link"
                       style="color: #231c1f"
+                      (click)="onStatusChange(data, 'stop', true)"
                     >
                       <span
                         nz-icon
@@ -210,21 +217,26 @@
                       >暂停流程
                     </button>
                   </li>
-                  } @if (data.state?.end){
+                  } @if (statusMap[data.id].end){
                   <li nz-menu-item>
                     <button
                       nz-button
-                      [disabled]="user?.get('isDeleted')"
                       nzType="link"
                       style="color: #231c1f"
+                      (click)="onStatusChange(data, 'end', true)"
                     >
                       <span nz-icon nzType="stop" nzTheme="outline"></span
                       >结束流程
                     </button>
                   </li>
-                  } @if (data.state?.del){
+                  } @if (statusMap[data.id].del){
                   <li nz-menu-item>
-                    <button nz-button nzType="link" style="color: #231c1f">
+                    <button
+                      nz-button
+                      nzType="link"
+                      (click)="onStatusChange(data, 'del', true)"
+                      style="color: #231c1f"
+                    >
                       <span nz-icon nzType="delete" nzTheme="outline"></span
                       >删除流程
                     </button>
@@ -253,13 +265,31 @@
     <div class="batch-toolbar-actions">
       <div class="ant-space ant-space-horizontal ant-space-align-center">
         <div class="ant-space-item" style="margin-right: 16px">
-          <button nz-button nzType="text" (click)="deleteSelected()">
+          <button nz-button nzType="text" (click)="statusSelected('del')">
             <span nz-icon nzType="delete"></span>
             删除
           </button>
         </div>
       </div>
     </div>
+    <div class="styles_cancel__AARoT">
+      <button nz-button nzType="text" (click)="statusSelected('strat')">
+        <span nz-icon nzType="caret-right" nzTheme="outline"></span>
+        批量开始
+      </button>
+    </div>
+    <div class="styles_cancel__AARoT">
+      <button nz-button nzType="text" (click)="statusSelected('stop')">
+        <span nz-icon nzType="pause-circle" nzTheme="outline"></span>
+        批量暂停
+      </button>
+    </div>
+    <div class="styles_cancel__AARoT">
+      <button nz-button nzType="text" (click)="statusSelected('end')">
+        <span nz-icon nzType="stop" nzTheme="outline"></span>
+        批量结束
+      </button>
+    </div>
     <div class="styles_cancel__AARoT">
       <button nz-button nzType="text" (click)="onAllChecked(false)">
         取消选中

+ 1 - 1
projects/textbook/src/modules/nav-admin/page-process/process-list/process-list.component.scss

@@ -100,7 +100,7 @@
   display: flex;
   justify-content: center;
   bottom: 80px;
-  left: calc(50% - 134px);
+  left: calc(50% - 376px);
   -webkit-transform: translate(0);
   transform: translate(0);
 }

+ 192 - 90
projects/textbook/src/modules/nav-admin/page-process/process-list/process-list.component.ts

@@ -74,7 +74,12 @@ export class ProcessListComponent implements OnInit {
   nodes: Array<nodes | any> = [];
   currentDepart: nodes | any = null;
 
-  eduProcessList: Array<any> = [];
+  eduProcessList: Array<Parse.Object> = [];
+  statusMap: any = {};
+  eduProcessLength: number = 0;
+  pageSize: number = 10;
+  pageIndex: number = 1;
+
   checkedShowFilter: boolean = false;
 
   checkedAll: boolean = false; //全选
@@ -95,69 +100,77 @@ export class ProcessListComponent implements OnInit {
   parentMap: Array<any> = [];
   parentList: Array<any> = [];
   setOfCheckedId = new Set<string>();
-  formatStatus = (e:any)=>{
-    if(e.status == '100'){
+  formatStatus = (e: any) => {
+    if (e.get('status') == '100') {
       return {
-        title:'已暂停',
-        color:'lime',
-        strat:true,
-        stop:true,
-        end:false,
-        del:false,
-      }
+        title: '已暂停',
+        color: 'lime',
+        strat: true,
+        stop: true,
+        end: false,
+        del: false,
+      };
     }
-    if(e?.deadline.iso && new Date() > new Date(e.deadline.iso) && e.status == '200'){
+    if (
+      e?.get('deadline') &&
+      new Date() > new Date(e?.get('deadline')) &&
+      e?.get('status') == '200'
+    ) {
       return {
-        title:'已结束',
-        color:'gold',
-        strat:false,
-        stop:false,
-        end:false,
-        del:true,
-      }
+        title: '已结束',
+        color: 'gold',
+        strat: false,
+        stop: false,
+        end: false,
+        del: true,
+      };
     }
-    if(e.status == '200'){
+    if (e?.get('status') == '200') {
       return {
-        title:'已完成',
-        color:'green',
-        strat:false,
-        stop:false,
-        end:true,
-        del:false,
-      }
+        title: '已完成',
+        color: 'green',
+        strat: false,
+        stop: false,
+        end: true,
+        del: false,
+      };
     }
-    if(!e?.startDate.iso || (new Date() < new Date(e.startDate.iso))){
+    if (!e?.get('startDate') || new Date() < new Date(e.get('startDate'))) {
       return {
-        title:'未开始',
-        color:'grey',
-        strat:true,
-        stop:false,
-        end:false,
-        del:true,
-      }
+        title: '未开始',
+        color: 'grey',
+        strat: true,
+        stop: false,
+        end: false,
+        del: true,
+      };
     }
-    if(!e.statuse && e.startDate.iso && new Date() >= new Date(e.startDate.iso) ){
+    if (
+      !e.get('status') &&
+      e?.get('startDate') &&
+      new Date() >= new Date(e?.get('startDate'))
+    ) {
       return {
-        title:'遴选中',
-        color:'blue',
-        strat:false,
-        stop:true,
-        end:true,
-        del:false,
-      }
+        title: '遴选中',
+        color: 'blue',
+        strat: false,
+        stop: true,
+        end: true,
+        del: false,
+      };
     }
-    if(e?.deadline.iso && (new Date() > new Date(e.deadline.iso))){
+    if (e?.get('deadline') && new Date() > new Date(e?.get('deadline'))) {
       return {
-        title:'已逾期',
-        color:'red',
-        strat:true,
-        stop:false,
-        end:false,
-        del:true,
-      }
+        title: '已逾期',
+        color: 'red',
+        strat: true,
+        stop: false,
+        end: false,
+        del: true,
+      };
     }
-    return
-  }
+    return;
+  };
   constructor(
     private route: Router,
     private activeRoute: ActivatedRoute,
@@ -207,77 +220,83 @@ export class ProcessListComponent implements OnInit {
   async onSearch(e: string) {
     this.nodes = await this.getDepart('', e);
   }
-  onSearchPro(e: string){
-    this.getProfile()
+  onSearchPro(e: string) {
+    this.pageIndex = 1
+    this.getEduProcess();
   }
   changeDepart(e: any) {
     this.currentDepart = e;
-    this.getProfile();
+    this.setOfCheckedId = new Set<string>();
+    this.checkedAll = false;
+    this.pageIndex = 1
+    this.getEduProcess();
   }
 
-  async getProfile() {
+  async getEduProcess() {
     this.eduProcessList = [];
     this.loading = true;
-    let query1= Parse.Query.fromJSON('EduProcess', {
+    let query1 = Parse.Query.fromJSON('EduProcess', {
       where: {
         $or: [
           {
-            name: { "$regex": `.*${this.searchValuePro}.*`},
+            name: { $regex: `.*${this.searchValuePro}.*` },
           },
-        ]
-      }
+        ],
+      },
     });
-    let query2= Parse.Query.fromJSON('EduProcess', {
+    let query2 = Parse.Query.fromJSON('EduProcess', {
       where: {
         $or: [
           {
-            code: { "$regex": `.*${this.searchValuePro}.*`},
+            code: { $regex: `.*${this.searchValuePro}.*` },
           },
-        ]
-      }
+        ],
+      },
     });
-    let query = Parse.Query.or(query1, query2)
+    let query = Parse.Query.or(query1, query2);
     query.include('profileSubmitted', 'profileSubmitted.user');
     query.notEqualTo('isDeleted', true);
-    query.equalTo('branch',this.currentDepart.key)
+    query.equalTo('branch', this.currentDepart.key);
+    this.eduProcessLength = await query.count();
+    query.skip(this.pageSize * (this.pageIndex - 1));
+    query.limit(this.pageSize);
     let r = await query.find();
-    let list: any[] = [];
+    // let list: any[] = [];
     r.forEach((item) => {
-      let _item = item.toJSON();
-      _item['checked'] = false;
-      _item['state'] = this.formatStatus(_item);
-      list.push(_item);
+      // let _item = item.toJSON();
+      // _item['checked'] = false;
+      // _item['state'] = this.formatStatus(_item);
+      this.statusMap[item.id] = this.formatStatus(item);
     });
-    this.eduProcessList = list;
+    this.eduProcessList = r;
     this.loading = false;
   }
-
+  //分页切换
+  pageIndexChange(e:any){
+    console.log(e);
+    this.pageIndex = e
+    this.getEduProcess()
+  }
   onAllChecked(checked: boolean): void {
     console.log(checked);
-    this.eduProcessList = this.eduProcessList.map((item) => {
-      item.checked = checked;
+    this.eduProcessList.forEach((item) => {
       if (checked) {
-        this.setOfCheckedId.add(item.user.objectId);
+        this.setOfCheckedId.add(item.id);
       } else {
-        this.setOfCheckedId.delete(item.user.objectId);
+        this.setOfCheckedId.delete(item.id);
       }
-      return item;
     });
     this.checkedAll = checked;
   }
   onItemChecked(id: string, e: boolean) {
-    let checkedAll = true;
-    this.eduProcessList = this.eduProcessList.map((item) => {
-      if (id == item.objectId) item.checked = e;
-      if (!item.checked) checkedAll = false;
-      return item;
-    });
     if (e) {
       this.setOfCheckedId.add(id);
     } else {
       this.setOfCheckedId.delete(id);
     }
-    this.checkedAll = checkedAll;
+    this.checkedAll = this.eduProcessList.every((item) =>
+      this.setOfCheckedId.has(item.id)
+    );
   }
   //新建打开弹窗
   async showModalDepart(type: string) {
@@ -353,25 +372,30 @@ export class ProcessListComponent implements OnInit {
   showModalOrganize() {
     this.message.warning('权限灰度中');
   }
-  deleteSelected() {
+  statusSelected(type:string) {
+    let map:any = {
+      'strat':'开始',
+      'stop':'暂停',
+      'end':'结束',
+    }
     this.modal.confirm({
       nzTitle: '批量删除',
-      nzContent: `删除后数据不可恢复,请谨慎操作`,
+      nzContent:type == 'del' ? `删除后数据不可恢复,请谨慎操作` : `确认批量${map[type]}吗`,
       nzOkText: '确认',
       nzOkType: 'primary',
-      nzOkDanger: true,
+      nzOkDanger: map[type] ? true : false,
       nzOnOk: async () => {
         let selectedList = this.eduProcessList.filter((item: any) =>
           this.setOfCheckedId.has(item?.id)
         );
         let deletePromiseList = selectedList.map((item: any) => {
           return new Promise((resolve) => {
-            item.set('isDeleted', true);
-            item.save();
+            resolve(this.onStatusChange(item,type))
           });
         });
         try {
           await Promise.all(deletePromiseList);
+          this.getEduProcess()
         } catch (err) {}
       },
       nzCancelText: '取消',
@@ -385,4 +409,82 @@ export class ProcessListComponent implements OnInit {
       this.route.navigate([url]);
     }
   }
+  //暂停流程
+  async onStatusChange(data: Parse.Object, type: string, end?:boolean):Promise<void> {
+    console.log(data, type);
+    switch (type) {
+      case 'strat':
+        if(data?.get('status') == '100'){
+          data?.set('status', null);
+        }
+        if(data?.get('startDate') > new Date()){
+          data?.set('startDate', new Date());
+        }
+        if(data?.get('deadline') < new Date()){
+          data?.set('deadline', new Date(new Date().getTime() + 60 * 1000 * 60 * 24 * 7));
+          console.warn('结束时间延长一周之后');
+        }
+        break;
+      case 'stop':
+        data?.set('status', '100');
+        break;
+      case 'end':
+        data?.set('status', '200');
+        data?.set('deadline', new Date());
+        break;
+      case 'del':
+        data?.set('isDeleted', true);
+        break;
+    }
+    await data.save()
+    if(end){
+     this.getEduProcess()
+    }
+  }
+
+
+  /* 批量预设(临时) */
+  // async saveProcess(){
+  //   let count = 0
+  //   let query = new Parse.Query('Department')
+  //   query.equalTo('parent',null)
+  //   let r = await query.find()
+  //   for (let index = 0; index < r.length; index++) {
+  //     const element = r[index];
+  //     let queryPareet = new Parse.Query('Department')
+  //     queryPareet.equalTo('parent', element.id)
+  //     queryPareet.limit(2000)
+  //     let prents = await queryPareet.find()
+  //     for (let index = 0; index < prents.length; index++) {
+  //       let item = prents[index];
+  //       let obj = Parse.Object.extend('EduProcess');
+  //       let eduProcess = new obj()
+  //       eduProcess?.set('company', {
+  //         __type: 'Pointer',
+  //         className: 'Company',
+  //         objectId: 'RbIKpmuaMC',
+  //       });
+  //       eduProcess?.set('branch', {
+  //         __type: 'Pointer',
+  //         className: 'Department',
+  //         objectId:element.id,
+  //       });
+  //       eduProcess?.set('department', {
+  //         __type: 'Pointer',
+  //         className: 'Department',
+  //         objectId: item.id,
+  //       });
+  //       eduProcess?.set('name', item.get('name'));
+  //       eduProcess?.set('desc', item.get('name') + '流程');
+  //       eduProcess?.set('code', item.get('code'));
+  //       if(element.get('name') == '全国出版单位') {
+  //         eduProcess?.set('startDate', new Date('2024-07-20 18:00'));
+  //         eduProcess?.set('deadline', new Date('2024-09-20 18:00'));
+  //       }
+  //       await eduProcess?.save();
+  //       count ++
+  //       console.log(count);
+  //     }
+  //   }
+  // }
 }

+ 129 - 8
projects/textbook/src/modules/nav-admin/page-role/page-role.component.html

@@ -8,7 +8,7 @@
   </nz-page-header-title>
   <nz-page-header-extra>
     <nz-space>
-      <button
+      <!-- <button
         style="background: #3e49b3; border: 1px #3e49b3"
         *nzSpaceItem
         nz-button
@@ -16,7 +16,7 @@
         (click)="addMember()"
       >
         添加账号
-      </button>
+      </button> -->
     </nz-space>
   </nz-page-header-extra>
 </nz-page-header>
@@ -58,7 +58,7 @@
                 <span nz-icon nzType="plus" nzTheme="outline"></span>添加部门
               </button>
             </li>
-            <li nz-menu-item>
+            <!-- <li nz-menu-item>
               <button
                 nz-button
                 nzType="link"
@@ -68,7 +68,7 @@
                 <span nz-icon nzType="merge" nzTheme="outline"></span>
                 新建组织
               </button>
-            </li>
+            </li> -->
           </ul>
         </nz-dropdown-menu>
       </div>
@@ -222,7 +222,7 @@
     <div nz-row class="depart-modal">
       <div nz-col nzSpan="12">
         <div class="row">
-          <div class="label">部门名称</div>
+          <div class="label">部门名称 <span style="color: #e8353e">*</span></div>
           <div class="value">
             <input
               nz-input
@@ -257,12 +257,133 @@
       </div>
       <div nz-col nzSpan="12">
         <div class="row">
-          <div class="label">上级部门</div>
+          <div class="label">上级部门 <span style="color: #e8353e">*</span></div>
           <div class="value">
             <input
               nz-input
-              placeholder="请选择上级"
+              placeholder="可击下方选择所属上级"
               [ngModel]="editObject.parent?.title"
+              (ngModelChange)="onSearchNodes($event,true)"
+              type="text"
+            />
+          </div>
+        </div>
+        <div class="select">
+          <div class="bar">
+            <a style="color: #86909c" (click)="onPre()">教材遴选</a>
+            @for (data of parentMap; track data.title) {
+            <span style="margin: 0 10px">/</span>
+            <a (click)="onPre(data, $index)">{{ data.title }}</a>
+            }
+          </div>
+          <div class="tree">
+            @for (data of parentList; track $index) {
+            <div class="li" (click)="onCheckedDepart(data)">
+              <label
+                nz-radio
+                [ngModel]="data.key == radio"
+                [nzValue]="data.key"
+                (click)="onCheckedDepart(data, true)"
+                >{{ data.title }}</label
+              >
+              @if (!data.isLeaf) {
+              <span nz-icon nzType="right" nzTheme="outline"></span>
+              }
+            </div>
+            }
+          </div>
+        </div>
+      </div>
+    </div>
+  </ng-container>
+  <div *nzModalFooter>
+    <button nz-button nzType="default" (click)="handleCancel()">取消</button>
+    <button
+      nz-button
+      nzType="primary"
+      style="background: #3e49b3; border: 1px #3e49b3"
+      (click)="handleOk()"
+    >
+      确定
+    </button>
+  </div>
+</nz-modal>
+
+<nz-modal
+  [(nzVisible)]="accountIsVisible"
+  nzTitle="添加账号(手机号及邮箱请至少填写一个,将发送登录账号)"
+  (nzOnCancel)="handleCancel()"
+  nzWidth="800px"
+  nzCentered
+>
+  <ng-container *nzModalContent>
+    <div nz-row class="depart-modal">
+      <div nz-col nzSpan="12">
+        <div class="row">
+          <div class="label">姓名 <span style="color: #e8353e">*</span></div>
+          <div class="value">
+            <input
+              nz-input
+              placeholder="请输入姓名"
+              [(ngModel)]="account.name"
+              type="text"
+            />
+          </div>
+        </div>
+        <div class="row">
+          <div class="label">手机号</div>
+          <div class="value">
+            <input
+              nz-input
+              placeholder="请输入手机号"
+              [(ngModel)]="account.phone"
+              type="text"
+            />
+          </div>
+        </div>
+        <div class="row">
+          <div class="label">邮箱</div>
+          <div class="value">
+            <input
+              nz-input
+              placeholder="请输入邮箱"
+              [(ngModel)]="account.email"
+              type="text"
+            />
+          </div>
+        </div>
+        <div class="row">
+          <div class="label">密码 <span style="color: #e8353e">*</span></div>
+          <div class="value">
+            <input
+              nz-input
+              placeholder="请输入密码"
+              [(ngModel)]="account.password"
+              type="text"
+            />
+          </div>
+        </div>
+        <div class="row">
+          <div class="label">人员类型</div>
+          <div class="value">
+            <input
+              nz-input
+              placeholder="请选择人员类型"
+              [(ngModel)]="account.companyType"
+              type="text"
+            />
+          </div>
+        </div>
+      </div>
+      <div nz-col nzSpan="12">
+        <div class="row">
+          <div class="label">上级部门 <span style="color: #e8353e">*</span></div>
+          <div class="value">
+            <input
+              nz-input
+              placeholder="请选择所属部门"
+              [ngModel]="account.department"
+              (ngModelChange)="onSearchNodes($event,true)"
               type="text"
             />
           </div>
@@ -286,7 +407,7 @@
                 >{{ data.title }}</label
               >
               @if (!data.isLeaf) {
-                <span nz-icon nzType="right" nzTheme="outline"></span>
+              <span nz-icon nzType="right" nzTheme="outline"></span>
               }
             </div>
             }

+ 194 - 72
projects/textbook/src/modules/nav-admin/page-role/page-role.component.ts

@@ -10,7 +10,7 @@ import { NzSpaceModule } from 'ng-zorro-antd/space';
 import { NzPageHeaderModule } from 'ng-zorro-antd/page-header';
 import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb';
 import { CommonCompModule } from '../../../services/common.modules';
-import { NzModalModule } from 'ng-zorro-antd/modal';
+import { NzModalModule, NzModalService } from 'ng-zorro-antd/modal';
 import {
   NzFormatEmitEvent,
   NzTreeModule,
@@ -28,7 +28,7 @@ interface nodes {
   title: string;
   key: string;
   isLeaf?: boolean;
-  isParent?: boolean;
+  branch?: string;
   children?: Array<any>;
 }
 interface depart {
@@ -69,7 +69,7 @@ export class PageRoleComponent implements OnInit {
   queryParams: any | undefined;
   fieldsArray: Array<any> | undefined;
   searchValue: string = ''; //搜索内容
-  searchValueNode:string = ''
+  searchValueNode: string = '';
   nodes: Array<nodes | any> = [];
   currentDepart: nodes | any = null;
 
@@ -93,13 +93,26 @@ export class PageRoleComponent implements OnInit {
   };
   parentMap: Array<any> = [];
   parentList: Array<any> = [];
-  radio:string = ''
+  radio: string = '';
+
+  /* 添加账号 */
+  accountIsVisible: boolean = false;
+  account: any = {
+    name: '',
+    phone: '',
+    email: '',
+    password: '',
+    identity: '',
+    department: '',
+    companyType: '',
+  };
 
   constructor(
     private route: Router,
     private activeRoute: ActivatedRoute,
     private nzContextMenuService: NzContextMenuService,
-    private message: NzMessageService,
+    private modal: NzModalService,
+    private message: NzMessageService
   ) {
     this.user = Parse.User.current();
     this.className = this.Department.className;
@@ -127,47 +140,62 @@ export class PageRoleComponent implements OnInit {
   async getDepart(
     parent?: string,
     searchValue?: string,
-    filter?:boolean
+    filter?: boolean
   ): Promise<Array<nodes>> {
     let nodes: any = [];
     let query = new Parse.Query('Department');
-    if(!filter){
+    if (!filter) {
       query.equalTo('parent', parent ? parent : undefined);
     }
     searchValue && query.contains('name', searchValue);
     query.notEqualTo('isDeleted', true);
-    query.select('code', 'name', 'branch', 'parent','type');
+    query.select('code', 'name', 'branch', 'parent', 'type');
     query.descending('createdAt');
     query.limit(2000);
+    if (this.activeDepart) query.notEqualTo('objectId', this.activeDepart?.id);
     let res = await query.find();
     res.forEach((item) => {
       nodes.push({
         title: item.get('name'),
         key: item.id,
         children: [],
-        isParent: item.get('type') =='单位' ? true : false, //是否是最下级
-        isLeaf: item.get('type') =='单位' ? true : false,
+        branch: item.get('branch'),
+        isLeaf: item.get('type') == '单位' ? true : false, //是否是最下级
       });
     });
     return nodes;
   }
   //搜索
-  async onSearchNodes(e:string){
-    this.nodes = await this.getDepart('',e, e ? true : false);
+  async onSearchNodes(e: string, modal?: boolean) {
+    if (modal) {
+      this.parentList = await this.getDepart('', e, true);
+      return;
+    }
+    this.nodes = await this.getDepart('', e, e ? true : false);
   }
   //添加成员
   addMember() {
-    this.message.warning('权限灰度中')
+    // this.message.warning('权限灰度中')
+    this.account = {
+      name: '',
+      phone: '',
+      email: '',
+      password: '',
+      identity: '',
+      department: '',
+      companyType: '',
+    };
+    this.accountIsVisible = true;
   }
   //展开/合并
   async nzEvent(event: NzFormatEmitEvent): Promise<void> {
     console.log(event);
     let node: any = event.node;
     if (event.eventName === 'expand') {
-      if (node.origin.isParent) {
-        node.addChildren([]);
-        return;
-      }
+      // if (node.origin.isParent) {
+      //   node.addChildren([]);
+      //   return;
+      // }
       if (node?._children.length <= 0) {
         let data = await this.getDepart(node.key);
         node.addChildren(data);
@@ -175,8 +203,8 @@ export class PageRoleComponent implements OnInit {
       console.log(this.nodes);
     } else {
       // if (node.origin.isParent) {
-        this.currentDepart = node.origin;
-        this.getProfile();
+      this.currentDepart = node.origin;
+      this.getProfile();
       // }
     }
   }
@@ -184,25 +212,29 @@ export class PageRoleComponent implements OnInit {
     this.profiles = [];
     this.loading = true;
     let queryParams = {
-      where : {
-        "$or": [{
-          "user": {
-            "$inQuery": {
-              "where": {
-                "$or": [{
-                    "department": { "$eq": this.currentDepart.key}
-                  },
-                ]
+      where: {
+        $or: [
+          {
+            user: {
+              $inQuery: {
+                where: {
+                  $or: [
+                    {
+                      department: { $eq: this.currentDepart.key },
+                    },
+                  ],
+                },
+                className: '_User',
               },
-              "className": "_User"
-            }
-          }
-        }]
-      }
-    }
-    let query = Parse.Query.fromJSON('Profile',queryParams);
+            },
+          },
+        ],
+      },
+    };
+    let query = Parse.Query.fromJSON('Profile', queryParams);
     query.include('user');
     query.notEqualTo('identity', '国家级管理员');
+    query.notEqualTo('isDeleted', true);
     let r = await query.find();
     let profiles: any[] = [];
     r.forEach((item) => {
@@ -227,8 +259,31 @@ export class PageRoleComponent implements OnInit {
     this.nzContextMenuService.create($event, menu);
   }
   //删除部门
-  onDelDepart() {
-    this.message.warning('权限灰度中')
+  async onDelDepart() {
+    this.modal.confirm({
+      nzTitle: '删除',
+      nzContent:'删除后数据不可恢复,请谨慎操作',
+      nzOkText: '确认',
+      nzOkType: 'primary',
+      nzOkDanger: true,
+      nzOnOk: async () => {
+        new Promise(async(resolve, reject) => {
+          if(this.activatedNode){
+            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 {
@@ -251,56 +306,93 @@ export class PageRoleComponent implements OnInit {
   //新建打开弹窗
   async showModalDepart(type: string) {
     this.parentList = this.nodes;
+    this.editObject = {
+      name: '',
+      code: '',
+      desc: '',
+      parent: '',
+      branch: '',
+    };
     if (type == 'edit') {
       let query = new Parse.Query('Department');
       let r = await query.get(this.activatedNode?.key);
       this.activeDepart = r;
-      this.parentMap = this.formatNode(this.activatedNode);
-      if(this.activatedNode?.parentNode?.origin.key){
-        this.parentList = await this.getDepart(this.activatedNode.parentNode.origin.key);
+      this.editObject = {
+        name: this.activeDepart.get('name'),
+        code: this.activeDepart.get('code'),
+        desc: this.activeDepart.get('desc'),
+        parent: {
+          title: this.activeDepart.get('parent')?.get('name'),
+          id: this.activeDepart.get('parent')?.id,
+        },
+        branch: this.activeDepart.get('branch'),
+      };
+      this.parentMap = await this.formatNode(this.activeDepart.get('parent')?.id);
+      if (this.activatedNode?.parentNode?.origin?.parentNode?.origin.key) {
+        this.parentList = await this.getDepart(
+          this.activatedNode?.parentNode?.origin?.parentNode?.origin.key
+        );
+      }
+    }else if(type == 'add' && this.activatedNode){
+      console.log(this.activatedNode);
+      this.editObject.parent = {
+          title: this.activatedNode.origin.title,
+          id: this.activatedNode.origin.key,
+      };
+      this.editObject.branch = this.activatedNode.origin.branch || this.activatedNode.origin.title
+      this.parentMap = await this.formatNode(this.activatedNode.origin.key);
+      if (this.activatedNode?.parentNode?.origin.key) {
+        this.parentList = await this.getDepart(
+          this.activatedNode.parentNode.origin.key
+        );
       }
     }
+    console.log(this.parentMap);
     this.editType = type;
     this.isVisible = true;
   }
   //格式化链
-  formatNode(node: NzTreeNode): Array<any> {
-    let arr = [];
-    if (node.parentNode?.origin.title) {
-      arr.push({
-        title: node.parentNode?.origin.title,
-        key: node.parentNode?.origin.key,
-      });
-      arr.unshift(...this.formatNode(node.parentNode));
+  async formatNode(id: string): Promise<Array<any>> {
+    let query = new Parse.Query('Department');
+    query.select('name', 'parent');
+    let r = await query.get(id);
+    let arr = [
+      {
+        title: r.get('name'),
+        key: r.id,
+      },
+    ];
+    if (r?.get('parent')) {
+      arr.unshift(...(await this.formatNode(r?.get('parent').id)));
     }
     return arr;
   }
-  async onPre(data?:any,index?:number){
-    if(!data){
+  async onPre(data?: any, index?: number) {
+    if (!data) {
       this.parentList = await this.getDepart();
-      this.parentMap = []
-      return
+      this.parentMap = [];
+      return;
     }
-    if(index == this.parentMap.length-1) return
-    this.parentMap.splice(index || 0+1)
+    if (index == this.parentMap.length - 1) return;
+    this.parentMap.splice(index || 0 + 1);
     this.parentList = await this.getDepart(data?.key);
   }
   //选择所属类别下级列表
   async onCheckedDepart(e: any, checked?: boolean) {
-    this.radio = e.key
+    this.radio = e.key;
     console.log(this.radio);
+    this.parentMap = await this.formatNode(e.key);
     if (checked) {
-      this.editObject = {
-        name: e.title,
-        code: '',
-        desc: '',
-        parent: e,
-        branch: '',
+      // this.editObject.name = e.title
+      this.editObject.parent = {
+        title: e.title,
+        id: e.key,
       };
+      this.editObject.branch = e.branch || e.title;
       return;
     }
-    if(e.isLeaf){
-      return
+    if (e.isLeaf) {
+      return;
     }
     this.parentMap.push({
       title: e.title,
@@ -308,9 +400,39 @@ export class PageRoleComponent implements OnInit {
     });
     this.parentList = await this.getDepart(e?.key);
   }
-  handleOk(): void {
-    this.message.warning('权限灰度中')
+  async handleOk():Promise<void> {
+    if(!this.editObject?.name || !this.editObject.parent?.id){
+      this.message.error('请填写完整信息')
+      return
+    }
+    if(this.activeDepart?.id && this.editType == 'edit'){
+      this.activeDepart.set('name',this.editObject?.name)
+      this.activeDepart.set('code',this.editObject?.code)
+      this.activeDepart.set('desc',this.editObject.desc)
+      this.activeDepart.set('parent',{
+        __type: 'Pointer',
+        className: 'Department',
+        objectId: this.editObject.parent?.id,
+      })
+      this.activeDepart.set('branch',this.editObject.branch)
+    }else{
+      let obj = Parse.Object.extend('Department')
+      this.activeDepart = new obj()
+      this.activeDepart?.set('name',this.editObject?.name)
+      this.activeDepart?.set('code',this.editObject?.code)
+      this.activeDepart?.set('desc',this.editObject.desc)
+      this.activeDepart?.set('parent',{
+        __type: 'Pointer',
+        className: 'Department',
+        objectId: this.editObject.parent?.id,
+      })
+      this.activeDepart?.set('branch',this.editObject.branch)
+    }
+    await this.activeDepart?.save()
     this.isVisible = false;
+    this.message.success(this.editType == 'edit' ? '保存' : '添加' + '成功')
+    this.activeDepart = undefined
+    this.nodes = await this.getDepart();
   }
 
   handleCancel(): void {
@@ -318,16 +440,16 @@ export class PageRoleComponent implements OnInit {
     this.isVisible = false;
     this.activatedNode = undefined;
     this.parentMap = [];
+
+    this.accountIsVisible = false;
+    this.account = null;
   }
 
   /* 组织 */
-  showModalOrganize(){
-    this.message.warning('权限灰度中')
+  showModalOrganize() {
+    this.message.warning('权限灰度中');
   }
-  goDateil(id:string){
-    this.route.navigate([
-      '/nav-admin/manage/user/edit',
-      { id:id },
-    ])
+  goDateil(id: string) {
+    this.route.navigate(['/nav-admin/manage/user/edit', { id: id }]);
   }
 }

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

@@ -105,7 +105,7 @@
       <tr>
         <td
           nzLeft
-          [nzChecked]="setOfCheckedId.has(data.objectId)"
+          [nzChecked]="setOfCheckedId.has(data.user.objectId)"
           (nzCheckedChange)="
             onItemChecked(data.objectId, data.user.objectId, $event)
           "

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

@@ -177,6 +177,14 @@
             <div class="value">{{ user?.get("name") || "未填写" }}</div>
           </div>
         </div>
+        <div nz-row>
+          <div nz-col nzSpan="8">
+            <div class="lable">用户名</div>
+            <div class="value">
+              {{ user?.get("username") || "未填写" }}
+            </div>
+          </div>
+        </div>
       </div>
       <div class="title">扩展信息</div>
       <div class="fill-template">
@@ -207,6 +215,10 @@
             <div class="lable">职务</div>
             <div class="value">{{ profile?.get("postName") || "未填写" }}</div>
           </div>
+          <div nz-col nzSpan="8">
+            <div class="lable">主要学科</div>
+            <div class="value">{{ profile?.get("majorSubject") || "未填写" }}</div>
+          </div>
         </div>
       </div>
       <div class="title">所属组织部门</div>