Explorar el Código

update 修改用户编辑页

cehn hace 8 meses
padre
commit
ad9d374d2a

+ 1 - 0
projects/textbook/src/modules/login/login/login.component.ts

@@ -32,6 +32,7 @@ export class LoginComponent implements OnInit{
   @ViewChild("codeloginSign") codeloginSign: any; 
 
   ngOnInit(){
+    localStorage.setItem('active','')
     let parseAuthing = new ParseAuthing({
       // 监听事件:登陆成功后,返回用户信息
       login:(user,authClient)=>{

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

@@ -1,5 +1,5 @@
 import { NgModule } from '@angular/core';
-import { RouterModule, Routes } from '@angular/router';
+import { RouterModule, Routes,RouteReuseStrategy } from '@angular/router';
 // import { CollectionEditComponent } from './collection/collection-edit/collection-edit.component';
 // import { CreateCollectionComponent } from './collection/create-collection/create-collection.component';
 // import { PageCollectionComponent } from './collection/page-collection/page-collection.component';
@@ -12,6 +12,7 @@ import { UserEditComponent } from './user-edit/user-edit.component';
 import { PageProcessComponent } from './page-process/page-process.component';
 import { TextbookDetailsComponent } from '../common/textbook-details/textbook-details.component';
 import { UserCreateComponent } from './page-user/user-create/user-create.component';
+import { ReuseService } from "../../services/route-reuse.service";
 const routes: Routes = [
   {
     path: '',
@@ -53,6 +54,9 @@ const routes: Routes = [
       {
         path: 'user', //用户列表
         component: PageUserComponent,
+        data:{
+          keep:true
+        }
       },
       {
         path: 'user/edit', //用户管理&编辑
@@ -77,5 +81,11 @@ const routes: Routes = [
 @NgModule({
   imports: [RouterModule.forChild(routes)],
   exports: [RouterModule],
+  providers:[
+    {
+      provide:RouteReuseStrategy,
+      useClass:ReuseService
+    }
+  ]
 })
 export class NavAdminRoutingModule {}

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

@@ -111,13 +111,13 @@
         <div nz-row>
           <div nz-col nzSpan="8">
             <div class="lable">创建时间</div>
-            <div class="value">
+            <div class="value pd4-8">
               {{ user?.createdAt | date : "yyyy-MM-dd HH:MM:ss" || "-" }}
             </div>
           </div>
           <div nz-col nzSpan="8">
             <div class="lable">最后登录时间</div>
-            <div class="value">
+            <div class="value pd4-8">
               {{
                 user?.get("lastLogin")
                   ? (user?.get("lastLogin") | date : "yyyy-MM-dd HH:MM:ss")
@@ -127,21 +127,21 @@
           </div>
           <div nz-col nzSpan="8">
             <div class="lable">最后登录IP</div>
-            <div class="value">{{ user?.get("lastIP") || "-" }}</div>
+            <div class="value pd4-8">{{ user?.get("lastIP") || "-" }}</div>
           </div>
         </div>
         <div nz-row>
           <div nz-col nzSpan="8">
             <div class="lable">登录次数</div>
-            <div class="value">{{ user?.get("loginsCount") || "-" }}</div>
+            <div class="value pd4-8">{{ user?.get("loginsCount") || "-" }}</div>
           </div>
           <div nz-col nzSpan="8">
-            <div class="lable">用户类型</div>
+            <div class="lable">用户类型 <span style="color: #e8353e">*</span></div>
             <nz-select
               style="width: 80%"
               nzShowSearch
               nzAllowClear
-              [disabled]="!edit"
+              [disabled]="!edit || tbookSer.profile.identity == '高校联系人'"
               nzPlaceHolder="请选择所属的身份类型"
               [(ngModel)]="profileJson.identity"
               [ngModelOptions]="{ standalone: true }"
@@ -156,7 +156,7 @@
           </div>
           <div nz-col nzSpan="8">
             <div class="lable">认证文件</div>
-            <div class="value">
+            <div class="value pd4-8">
               @if (profile?.get('identityFile')) {
               <a (click)="openUrl(profile?.get('identityFile'))">查看文件</a>
               }@else { 未上传 }
@@ -182,7 +182,7 @@
       <div class="fill-template">
         <div nz-row>
           <div nz-col nzSpan="8">
-            <div class="lable">手机号</div>
+            <div class="lable">手机号 <span style="color: #e8353e">*</span></div>
             <div class="value">
               <input
                 nz-input
@@ -195,7 +195,7 @@
             </div>
           </div>
           <div nz-col nzSpan="8">
-            <div class="lable">邮箱</div>
+            <div class="lable">邮箱 <span style="color: #e8353e">*</span></div>
             <div class="value">
               <input
                 nz-input
@@ -208,7 +208,7 @@
             </div>
           </div>
           <div nz-col nzSpan="8">
-            <div class="lable">姓名</div>
+            <div class="lable">姓名 <span style="color: #e8353e">*</span></div>
             <div class="value">
               <input
                 nz-input
@@ -223,7 +223,7 @@
         </div>
         <div nz-row>
           <div nz-col nzSpan="8">
-            <div class="lable">用户名</div>
+            <div class="lable">用户名 <span style="color: #e8353e">*</span></div>
             <div class="value">
               <input
                 nz-input
@@ -356,7 +356,7 @@
                 nz-input
                 type="text"
                 [disabled]="!edit"
-                [(ngModel)]="profileJson.postName"
+                [(ngModel)]="profileJson.majorSubject"
                 placeholder="请填写主要学科"
               />
               <!-- {{ profile?.get("majorSubject") || "未填写" }} -->
@@ -507,3 +507,6 @@
     </button>
   </div>
 </nz-modal>
+<div class="loading" [hidden]="!loading">
+  <nz-spin nzSimple [nzSize]="'large'"></nz-spin>
+</div>

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

@@ -8,6 +8,14 @@
   // white-space: nowrap;
   // text-overflow: ellipsis;
 }
+.back {
+  font-family: PingFang SC;
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 22px;
+  text-align: left;
+  cursor: pointer;
+}
 .user-header {
   display: flex;
   justify-content: space-between;
@@ -79,7 +87,7 @@
     }
     .value{
       width: 80%;
-      padding: 4px 8px;
+      // padding: 4px 8px;
       background: #f9f9f9;
       border-radius: 4px;
       color: #242722;
@@ -161,6 +169,21 @@
     }
   }
 }
+.loading{
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  text-align: center;
+  height: 100vh;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: rgb(0 0 0 / 30%);
+}
+.pd4-8{
+  padding: 4px 8px;
+}
 ::ng-deep .ant-page-header-heading-title {
   white-space: normal;
 }

+ 118 - 23
projects/textbook/src/modules/nav-admin/user-edit/user-edit.component.ts

@@ -18,7 +18,7 @@ import { NzImageModule } from 'ng-zorro-antd/image';
 import { NzSelectModule } from 'ng-zorro-antd/select';
 import { MatButtonModule } from '@angular/material/button';
 import { provinces } from '../../../services/provinces';
-
+import { NzModalService } from 'ng-zorro-antd/modal';
 
 @Component({
   selector: 'app-user-edit',
@@ -36,7 +36,8 @@ import { provinces } from '../../../services/provinces';
     NzModalModule,
     NzRadioModule,
     NzImageModule,
-    NzSelectModule,MatButtonModule
+    NzSelectModule,
+    MatButtonModule,
   ],
   standalone: true,
 })
@@ -64,20 +65,22 @@ export class UserEditComponent implements OnInit {
   isShowModal: boolean = false;
   searchValue: string = ''; //搜索部门内容
   unitTypes: Array<any> = [];
-  userJson: any = { //user编辑数据
-    email:'',
-    phone:'',
-    name:'',
-    username:'',
-  }
-  profileJson: any = { //身份编辑数据
-    identity:'',
-    telephone:'',
-    province:'',
-    departmentName:'',
-    postName:'',
-    majorSubject:''
-  }
+  userJson: any = {
+    //user编辑数据
+    email: '',
+    phone: '',
+    name: '',
+    username: '',
+  };
+  profileJson: any = {
+    //身份编辑数据
+    identity: '',
+    telephone: '',
+    province: '',
+    departmentName: '',
+    postName: '',
+    majorSubject: '',
+  };
   userType: Array<string> = ['教师', '评审专家', '高校联系人', '工作联系人'];
   provinces: Array<string> = provinces.options; //省份
 
@@ -86,7 +89,8 @@ export class UserEditComponent implements OnInit {
     private activeRoute: ActivatedRoute,
     private router: Router,
     private message: NzMessageService,
-    private nzImageService: NzImageService
+    private nzImageService: NzImageService,
+    private modal: NzModalService
   ) {}
 
   ngOnInit() {
@@ -112,7 +116,9 @@ export class UserEditComponent implements OnInit {
       let arr = ['教师', '评审专家', '高校联系人'];
       if (this.tbookSer.profile.identity == '国家级管理员') {
         this.edit = true;
-      } else if (this.tbookSer.profile.identity == '工作联系人' && arr.includes(this.profile.get('identity'))
+      } else if (
+        this.tbookSer.profile.identity == '工作联系人' &&
+        arr.includes(this.profile.get('identity'))
       ) {
         this.userType = ['教师', '评审专家', '工作联系人'];
         this.edit = true;
@@ -156,7 +162,7 @@ export class UserEditComponent implements OnInit {
       this.message.warning('同级身份暂无权限操作');
       return;
     }
-    this.password = this.password.trim();
+    this.password = this.password?.trim();
     if (!this.password) {
       this.message.warning('密码格式错误');
       return;
@@ -171,8 +177,8 @@ export class UserEditComponent implements OnInit {
     this.isVisible = false;
   }
   //切换单位类型
-  onChangeType(){
-    this.userDataJson.department = null
+  onChangeType() {
+    this.userDataJson.department = null;
   }
   //选择部门
   async showModalDepart() {
@@ -295,8 +301,97 @@ export class UserEditComponent implements OnInit {
       this.nzImageService.preview(images, { nzZoom: 1.5, nzRotate: 0 });
     }
   }
+  /* 修改账号 */
+  loading: boolean = false;
+  submitForm(type: string) {
+    if (this.loading) return;
+    this.loading = true;
+    if (type == 'save') {
+      this.updateUserJson();
+    } else {
+      this.userJson = this.user.toJSON();
+      this.profileJson = this.profile.toJSON();
+      this.userDataJson = {
+        companyType: this.profile?.get('companyType'),
+        department: this.user.get('department'),
+      };
+      this.loading = false;
+    }
+  }
+  async updateUserJson() {
+    //修改用户数据
+    console.log(this.userJson);
+    console.log(this.profileJson);
+    this.userJson.username = this.userJson?.username?.trim();
+    this.userJson.email = this.userJson?.email?.trim();
+    this.userJson.phone = this.userJson?.phone?.trim();
+    this.userJson.name = this.userJson?.name?.trim();
+    if (!(await this.authVrifly())) {
+      this.loading = false;
+      return;
+    }
+    try {
+      this.user?.set('username', this.userJson?.username);
+      this.user?.set('name', this.userJson?.name);
+      this.user?.set('phone', this.userJson?.phone);
+      this.userJson?.email && this.user?.set('email', this.userJson?.email);
+      await this.user.save();
+      
+      this.profile?.set('companyType', this.userDataJson.companyType);
+      this.profile?.set('email', this.userJson.email);
+      this.profile?.set('identity', this.profileJson.identity);
+
+      this.profile?.set('telephone', this.profileJson.telephone);
+      this.profile?.set('province', this.profileJson.province);
+      this.profile?.set('departmentName', this.profileJson.departmentName);
+      this.profile?.set('postName', this.profileJson.postName);
+      this.profile?.set('majorSubject', this.profileJson.majorSubject);
+
+      await this.profile?.save();
+      this.loading = false;
+      this.modal.success({
+        nzTitle: '修改成功',
+        nzContent: '',
+        nzOnOk: () => {},
+      });
+    } catch (err: any) {
+      console.warn('添加用户错误', err);
+      this.loading = false;
+      this.message.error(
+        err?.Error || '错误:请检查用户或邮箱及手机号是否已存在'
+      );
+      return;
+    }
+  }
 
-  submitForm(type:string){
-    this.message.warning('权限暂未开放')
+  async authVrifly(): Promise<boolean | undefined> {
+    this.userJson.username = this.userJson?.username?.trim();
+    this.userJson.email = this.userJson?.email?.trim();
+    this.userJson.phone = this.userJson?.phone?.trim();
+    this.userJson.name = this.userJson?.name?.trim();
+    if (!this.userJson?.username || !this.userJson?.name || !this.userJson.phone || !this.userJson?.email) {
+      this.message.warning('请填写必填项');
+      return;
+    }
+    if (!this.profileJson.identity) {
+      this.message.error('请选择人员类型');
+      return;
+    }
+    let a = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/;
+    if (this.userJson.phone && !String(this.userJson.phone).match(a)) {
+      this.message.error('请填写正确手机号');
+      return;
+    }
+    let m =
+      /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+    if (!String(this.userJson.email).match(m)) {
+      this.message.error('邮箱格式有误');
+      return;
+    }
+    if (this.userJson.phone != this.user.get('phone') && !(await this.tbookSer.userFind(this.userJson.phone))) {
+      this.message.error('手机号已存在');
+      return;
+    }
+    return true;
   }
 }

+ 76 - 0
projects/textbook/src/services/route-reuse.service.ts

@@ -0,0 +1,76 @@
+import {
+  ActivatedRouteSnapshot,
+  DetachedRouteHandle,
+  RouteReuseStrategy,
+} from '@angular/router';
+
+export class ReuseService implements RouteReuseStrategy {
+  storedRouteHandles = new Map<string, DetachedRouteHandle>();
+  //用来判断跳转时是否需要存储页面
+  from = '';
+  to = '';
+  //用来判断跳转时是否要读取之前存储的页面
+  reuseFrom = '';
+  reuseTo = '';
+
+  shouldReuseRoute(
+    from: ActivatedRouteSnapshot,
+    to: ActivatedRouteSnapshot
+  ): boolean {
+    if (from.routeConfig) {
+      this.from = this.getPath(from);
+    }
+    if (to.routeConfig) {
+      this.to = this.getPath(to);
+    }
+    return from.routeConfig === to.routeConfig;
+  }
+
+  shouldDetach(route: ActivatedRouteSnapshot): boolean {
+    console.log(this.from);
+    console.log(this.to);
+    
+    // 判断是否执行store
+    const f =
+      (this.from === 'nav-admin/manage/user' && this.to === 'nav-admin/manage/user/edit') ||
+      (this.from === 'b' && this.to === 'c');
+    if (f) {
+      this.reuseFrom = this.to;
+      this.reuseTo = this.from;
+    }
+    return f;
+  }
+
+  store(
+    route: ActivatedRouteSnapshot,
+    detachedTree: DetachedRouteHandle
+  ): void {
+    // 进行路由复用存储
+    this.storedRouteHandles.set(this.getPath(route), detachedTree);
+  }
+
+  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
+    if (this.from === this.reuseFrom && this.to === this.reuseTo) {
+      // 读取路由复用
+      return this.storedRouteHandles.get(
+        this.getPath(route)
+      ) as DetachedRouteHandle;
+    } else {
+      return null;
+    }
+  }
+
+  shouldAttach(route: ActivatedRouteSnapshot): boolean {
+    if (this.reuseFrom && this.reuseTo && this.from && this.to) {
+      return this.from === this.reuseFrom && this.to === this.reuseTo;
+    } else {
+      return false;
+    }
+  }
+
+  private getPath(route: ActivatedRouteSnapshot | any): string {
+    // 截取路由地址中最小子节点
+    let url = route['_routerState'].url.split('/');
+    return url[url.length - 1].split('?')[0];
+  }
+}