浏览代码

Merge branch 'master' of http://git.fmode.cn:3000/csdn1233/s202226701049

未来全栈 3 月之前
父节点
当前提交
88a64b3ba6
共有 39 个文件被更改,包括 1335 次插入33 次删除
  1. 5 2
      AIart-app/src/app/app.component.ts
  2. 3 0
      AIart-app/src/app/interest-search/interest-search.component.html
  3. 25 2
      AIart-app/src/app/tab1/tab1.page.html
  4. 138 0
      AIart-app/src/app/tab1/tab1.page.scss
  5. 4 0
      AIart-app/src/app/tab1/tab1.page.ts
  6. 3 2
      AIart-app/src/app/tab5/tab5.page.html
  7. 5 1
      AIart-app/src/app/tab5/tab5.page.ts
  8. 5 0
      AIart-app/src/app/tabs/tabs.routes.ts
  9. 77 0
      AIart-app/src/app/user-login/user-login.component.html
  10. 35 0
      AIart-app/src/app/user-login/user-login.component.scss
  11. 22 0
      AIart-app/src/app/user-login/user-login.component.spec.ts
  12. 64 0
      AIart-app/src/app/user-login/user-login.component.ts
  13. 二进制
      AIart-app/src/assets/img/background.png
  14. 二进制
      AIart-app/src/assets/img/banner1.jpg
  15. 二进制
      AIart-app/src/assets/img/banner2.jpg
  16. 二进制
      AIart-app/src/assets/img/banner3.jpeg
  17. 二进制
      AIart-app/src/assets/img/banner4.png
  18. 二进制
      AIart-app/src/assets/img/login_icon.png
  19. 二进制
      AIart-app/src/assets/img/login_icon2.png
  20. 二进制
      AIart-app/src/assets/img/login_icon3.png
  21. 二进制
      AIart-app/src/assets/img/login_icon4.png
  22. 二进制
      AIart-app/src/assets/img/lunbo1.png
  23. 二进制
      AIart-app/src/assets/img/lunbo2.png
  24. 二进制
      AIart-app/src/assets/img/lunbo3.png
  25. 二进制
      AIart-app/src/assets/img/lunbo4.png
  26. 二进制
      AIart-app/src/assets/img/next.png
  27. 二进制
      AIart-app/src/assets/img/prev.png
  28. 2 2
      AIart-app/src/lib/ncloud.ts
  29. 33 0
      AIart-app/src/lib/user/model-user-edit/model-user-edit.component.html
  30. 0 0
      AIart-app/src/lib/user/model-user-edit/model-user-edit.component.scss
  31. 22 0
      AIart-app/src/lib/user/model-user-edit/model-user-edit.component.spec.ts
  32. 63 0
      AIart-app/src/lib/user/model-user-edit/model-user-edit.component.ts
  33. 39 0
      AIart-app/src/lib/user/model-user-login/model-user-login.component.html
  34. 0 0
      AIart-app/src/lib/user/model-user-login/model-user-login.component.scss
  35. 22 0
      AIart-app/src/lib/user/model-user-login/model-user-login.component.spec.ts
  36. 91 0
      AIart-app/src/lib/user/model-user-login/model-user-login.component.ts
  37. 569 0
      AIart-prod/UML Presentation.md
  38. 108 1
      AIart-prod/communitySharing.md
  39. 0 23
      AIart-prod/text.md

+ 5 - 2
AIart-app/src/app/app.component.ts

@@ -1,12 +1,15 @@
 import { Component } from '@angular/core';
+import { FormsModule } from '@angular/forms';
 import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
 
+
 @Component({
   selector: 'app-root',
   templateUrl: 'app.component.html',
   standalone: true,
-  imports: [IonApp, IonRouterOutlet],
+  imports: [IonApp, IonRouterOutlet, FormsModule],
 })
 export class AppComponent {
-  constructor() {}
+  constructor() { }
+
 }

+ 3 - 0
AIart-app/src/app/interest-search/interest-search.component.html

@@ -1,6 +1,9 @@
 <!-- src/app/interest-search/interest-search.component.html -->
 <ion-header [translucent]="true">
   <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button default-href="/tabs/tab1" style="color:black;"></ion-back-button>
+    </ion-buttons>
     <ion-title style="font-family: 'Courier New', Courier, monospace;">
       <span style="font-weight: bold;">调查问卷</span>
     </ion-title>

+ 25 - 2
AIart-app/src/app/tab1/tab1.page.html

@@ -43,13 +43,36 @@
     <!-- 首部导航栏部分结束 -->
   </div>
   <!-- 轮播图部分开始 -->
-  <div>
+  <!-- <div>
     <ion-segment-view>
       <img alt="wu" src="../../assets/img/study.png" style="border-radius: 8px;position: relative;margin: 15px;display:flex ;align-items: center;
     justify-content: center;height: 200px;width: 90%;" />
     </ion-segment-view>
-  </div>
+  </div> -->
   <!-- 轮播图部分结束 -->
+  <!-- 创建外部展示容器 -->
+  <div class="banner-container">
+    <!-- 创建图片存储容器 -->
+    <!-- 轮播图圆点 -->
+    <input type="radio" name="radio-set" checked="checked" id="banner-control-1">
+    <a class="banner-nav-a" href="#banner01"></a>
+    <input type="radio" name="radio-set" id="banner-control-2">
+    <a class="banner-nav-a" href="#banner02"></a>
+    <input type="radio" name="radio-set" id="banner-control-3">
+    <a class="banner-nav-a" href="#banner03"></a>
+    <input type="radio" name="radio-set" id="banner-control-4">
+    <a class="banner-nav-a" href="#banner04"></a>
+    <input type="radio" name="radio-set" id="banner-control-5">
+    <a class="banner-nav-a" href="#banner05"></a>
+    <div class="banner-img-container">
+      <img src="../../assets/img/lunbo4.png" alt="">
+      <img src="../../assets/img/lunbo1.png" alt="">
+      <img src="../../assets/img/lunbo2.png" alt="">
+      <img src="../../assets/img/lunbo3.png" alt="">
+      <img src="../../assets/img/study.png" alt="">
+    </div>
+  </div>
+
   <!-- 中部导航栏部分开始 -->
   <div style="display: flex;align-items: center;justify-content: center;margin-bottom: 10px;">
     <div class="ion-activatable ripple-parent rounded-rectangle">

+ 138 - 0
AIart-app/src/app/tab1/tab1.page.scss

@@ -65,4 +65,142 @@
     font-size: 14px;
     font-weight: bold;
     text-align: center;
+}
+
+
+
+/* 自动轮播样式 */
+.banner-container {
+    width: 1200px;
+    height: 200px;
+    /* 轮播图居中 */
+    margin-bottom: 10px;
+    /* 隐藏超出展示容器的内容 */
+    overflow: hidden;
+    position: relative;
+}
+
+.banner-container .banner-img-container {
+    width: 6000px;
+    height: 200px;
+    overflow: hidden;
+    position: absolute;
+    /* 开启弹性盒,让图片横向排列 */
+    display: flex;
+    transition: transform 0.6s ease;
+}
+
+.banner-container .banner-img-container img {
+    width: 400px;
+    height: 200px;
+}
+
+/* 动画关键帧 */
+@keyframes run {
+
+    0%,
+    10% {
+        /* margin-left: 0; */
+        transform: translateX(0);
+    }
+
+    20%,
+    30% {
+        transform: translateX(-400px);
+    }
+
+    40%,
+    50% {
+        transform: translateX(-800px);
+    }
+
+    60%,
+    70% {
+        transform: translateX(-1200px);
+    }
+
+    80%,
+    90% {
+        transform: translateX(-1600px);
+    }
+
+    100% {
+        transform: translateX(0);
+    }
+}
+
+/* 轮播图圆点样式 */
+.banner-container a {
+    width: 18px;
+    height: 8px;
+    background: #898b8e;
+    position: absolute;
+    bottom: 1rem;
+    border-radius: 7px;
+    margin: 0;
+    z-index: 1;
+}
+
+.banner-container input {
+    width: 18px;
+    height: 8px;
+    position: absolute;
+    bottom: 1rem;
+    margin: 0;
+    cursor: pointer;
+    z-index: 2;
+    opacity: 0;
+}
+
+/* 设置导航圆点偏移量(居中布局)*/
+#banner-control-1,
+#banner-control-1+.banner-nav-a {
+    left: 9%;
+}
+
+#banner-control-2,
+#banner-control-2+.banner-nav-a {
+    left: 12%;
+}
+
+#banner-control-3,
+#banner-control-3+.banner-nav-a {
+    left: 15%;
+}
+
+#banner-control-4,
+#banner-control-4+.banner-nav-a {
+    left: 18%;
+}
+
+#banner-control-5,
+#banner-control-5+.banner-nav-a {
+    left: 21%;
+}
+
+/* 设置高亮 */
+/*当 input 被选中时 他的兄弟级a标签高亮展示*/
+input:checked+.banner-nav-a {
+    background-color: #b64d24;
+}
+
+/* 设置轮播图动画 */
+#banner-control-1:checked~.banner-img-container {
+    transform: translateX(0px);
+}
+
+#banner-control-2:checked~.banner-img-container {
+    transform: translateX(-400px);
+}
+
+#banner-control-3:checked~.banner-img-container {
+    transform: translateX(-800px);
+}
+
+#banner-control-4:checked~.banner-img-container {
+    transform: translateX(-1200px);
+}
+
+#banner-control-5:checked~.banner-img-container {
+    transform: translateX(-1600px);
 }

+ 4 - 0
AIart-app/src/app/tab1/tab1.page.ts

@@ -21,6 +21,7 @@ import { Router } from '@angular/router';
 })
 export class Tab1Page {
   constructor(private router: Router) { }
+
   goToInterestTest() {
     this.router.navigate(['/tabs/interest-test'])
   }
@@ -33,4 +34,7 @@ export class Tab1Page {
   goToInterestSearch() {
     this.router.navigate(['/tabs/interest-search'])
   }
+
+
+
 }

+ 3 - 2
AIart-app/src/app/tab5/tab5.page.html

@@ -26,8 +26,9 @@
           </div>
         </div>
       </div>
-      <div style="display: flex;align-items: center;margin-right: 10px;">
-        <ion-icon name="chevron-forward-outline"></ion-icon>
+      <div style="display: flex;align-items: center;margin-right: 20px;">
+        <ion-icon name="chevron-forward-outline" class="rounded-rectangle" (click)="goUserLogin()"
+          style="width: 25px;height: 25px;"></ion-icon>
       </div>
     </div>
     <div style="display: flex;align-items: center;justify-content: center;gap: 40px;

+ 5 - 1
AIart-app/src/app/tab5/tab5.page.ts

@@ -1,6 +1,7 @@
 import { Component } from '@angular/core';
 import { IonHeader, IonToolbar, IonTitle, IonContent, IonSearchbar, IonIcon } from '@ionic/angular/standalone';
 import { ExploreContainerComponent } from '../explore-container/explore-container.component';
+import { Router } from '@angular/router';
 
 @Component({
   selector: 'app-tab5',
@@ -11,5 +12,8 @@ import { ExploreContainerComponent } from '../explore-container/explore-containe
     IonSearchbar, IonIcon],
 })
 export class tab5Page {
-  constructor() { }
+  constructor(private router: Router) { }
+  goUserLogin() {
+    this.router.navigate(['/tabs/user-login'])
+  }
 }

+ 5 - 0
AIart-app/src/app/tabs/tabs.routes.ts

@@ -51,6 +51,11 @@ export const routes: Routes = [
         loadComponent: () =>
           import('../interest-search/interest-search.component').then((m) => m.InterestSearchComponent),
       },
+      {
+        path: 'user-login',
+        loadComponent: () =>
+          import('../user-login/user-login.component').then((m) => m.UserLoginComponent),
+      },
       {
         path: '',
         redirectTo: '/tabs/tab1',

+ 77 - 0
AIart-app/src/app/user-login/user-login.component.html

@@ -0,0 +1,77 @@
+<ion-header [translucent]="true">
+  <ion-toolbar class="custom-toolbar">
+    <ion-buttons slot="start">
+      <ion-back-button default-href="/tabs/tab5" style="color:black;"></ion-back-button>
+    </ion-buttons>
+    @if(!currentUser?.id){
+    <ion-title class="custom-title">
+      用户登录注册
+    </ion-title>
+    }
+    @if(currentUser?.id){
+    <ion-title class="custom-title">
+      个人信息
+    </ion-title>
+    }
+  </ion-toolbar>
+</ion-header>
+<ion-content [fullscreen]="true" style="padding-top: 3px;">
+
+  <!-- 用户登录状态 -->
+  <ion-card style="height: 90%;width: 90%;">
+    <!-- 未登录 -->
+    @if(!currentUser?.id){
+    <ion-card-header style="display: flex;align-items: center;">
+      <ion-card-title>Register/Login</ion-card-title>
+      <ion-card-subtitle>no user information</ion-card-subtitle>
+    </ion-card-header>
+    }
+    <!-- 已登录 -->
+    @if(currentUser?.id){
+    <ion-card-header class="card-header">
+      <img [src]="currentUser?.get('avatar')|| '../../assets/image/doctor7.png'" alt="头像" class="avatar" />
+      <div class="user-info">
+        <ion-card-title>账号:{{currentUser?.get("username")}}</ion-card-title>
+        <ion-card-subtitle>
+          姓名: {{currentUser?.get("realname") || "-"}}
+          性别: {{currentUser?.get("gender") || "-"}}
+          年龄: {{currentUser?.get("age") || "-"}}
+        </ion-card-subtitle>
+      </div>
+    </ion-card-header>
+    }
+    <ion-card-content>
+      @if(!currentUser?.id){
+      <img src="../../assets/img/background.png" alt="登录注册">
+      <ion-button expand="block" (click)="signup()">注册</ion-button>
+      <ion-button expand="block" (click)="login()">登录</ion-button>
+      <div style="display: flex;align-items: center;">
+        <img style="height: 40px;width: 40px;border-radius: 20px;" src="../../assets/img/login_icon.png" alt="">
+        <img style="height: 40px;width: 40px;border-radius: 10px;" src="../../assets/img/login_icon2.png" alt="">
+        <!-- <img style="height: 40px;width: 40px;border-radius: 20px;" src="../../assets/img/login_icon3.png" alt="">
+        <img style="height: 40px;width: 40px;border-radius: 20px;" src="../../assets/img/login_icon4.png" alt=""> -->
+      </div>
+      <span style="margin-left: 70px;">Forgot your password?</span>
+      <!-- <img src="../../assets/img/login_icon.png" alt=""> -->
+      }
+      @if(currentUser?.id){
+      <ion-button expand="block" (click)="editUser()">编辑资料</ion-button>
+      <ion-button expand="block" (click)="logout()">登出</ion-button>
+      }
+    </ion-card-content>
+  </ion-card>
+  @if(currentUser?.id){
+  <ion-card class="memo-card">
+    <h2 class="memo-title">健康备忘录</h2>
+    <p class="memo-description">写下您问诊的医生名或者心动的科普知识,便于您下次查找(点击标签可删除)</p>
+    <edit-tag (onTagChange)="setTagsValue($event)"></edit-tag>
+
+    <h2 class="memo-title">收藏夹</h2>
+    <ul class="tag-list">
+      @for(tag of editTags; track tag;){
+      <li class="tag-item">{{tag}}</li>
+      }
+    </ul>
+  </ion-card>
+  }
+</ion-content>

+ 35 - 0
AIart-app/src/app/user-login/user-login.component.scss

@@ -0,0 +1,35 @@
+.custom-toolbar {
+    --background: rgba(255, 255, 255, 0.8);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    padding: 0;
+}
+
+.custom-title {
+    font-size: 17px;
+    color: #000000;
+    text-align: center;
+    margin: 0;
+
+}
+
+ion-card-content img {
+    border-radius: 100%;
+    width: 150px;
+    height: 150px;
+    margin-left: 75px;
+    margin-bottom: 15px;
+}
+
+ion-card-content ion-button {
+    width: 85%;
+    margin-left: 22px;
+    --background: #bfc7ce;
+    --background-hover: #bfc7ce;
+    --background-activated: #bfc7ce;
+    --background-focused: #bfc7ce;
+    --color: black;
+    font-weight: bold;
+    margin-bottom: 15px;
+}

+ 22 - 0
AIart-app/src/app/user-login/user-login.component.spec.ts

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

+ 64 - 0
AIart-app/src/app/user-login/user-login.component.ts

@@ -0,0 +1,64 @@
+import { Component, OnInit } from '@angular/core';
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardContent, IonButton, IonCardHeader, IonCardTitle, IonCardSubtitle, ModalController, IonButtons, IonBackButton } from '@ionic/angular/standalone';
+import { EditTagComponent } from '../edit-tag/edit-tag.component';
+import { CloudUser } from 'src/lib/ncloud';
+import { openUserLoginModal } from 'src/lib/user/model-user-login/model-user-login.component';
+import { openUserEditModal } from 'src/lib/user/model-user-edit/model-user-edit.component';
+
+@Component({
+  selector: 'app-user-login',
+  templateUrl: './user-login.component.html',
+  styleUrls: ['./user-login.component.scss'],
+  standalone: true,
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent,
+    IonCard, IonCardContent, IonButton, IonCardHeader, IonCardTitle, IonCardSubtitle,
+    EditTagComponent, IonButtons, IonBackButton,
+  ],
+})
+export class UserLoginComponent implements OnInit {
+  ngOnInit(): void {
+
+  }
+  currentUser: CloudUser | undefined
+  constructor(private modalCtrl: ModalController) {
+    this.currentUser = new CloudUser();
+  }
+  async login() {
+    // 弹出登录窗口
+    let user = await openUserLoginModal(this.modalCtrl);
+    if (user?.id) {
+      this.currentUser = user
+    }
+  }
+  async signup() {
+    // 弹出注册窗口
+    let user = await openUserLoginModal(this.modalCtrl, "signup");
+    if (user?.id) {
+      this.currentUser = user
+    }
+  }
+  logout() {
+    this.currentUser?.logout();
+  }
+
+  editUser() {
+    openUserEditModal(this.modalCtrl)
+  }
+
+  editTags: Array<String> = []
+  async setTagsValue(ev: any) {
+    let currentUser = new CloudUser();
+    let userPrompt = ``
+    if (!currentUser?.id) {
+      console.log("用户未登录,请登录后重试");
+      let user = await openUserLoginModal(this.modalCtrl);
+      if (!user?.id) {
+        return
+      }
+      currentUser = user;
+    }
+    //console.log("setTagsValue",ev);
+    this.editTags = ev;
+  }
+
+}

二进制
AIart-app/src/assets/img/background.png


二进制
AIart-app/src/assets/img/banner1.jpg


二进制
AIart-app/src/assets/img/banner2.jpg


二进制
AIart-app/src/assets/img/banner3.jpeg


二进制
AIart-app/src/assets/img/banner4.png


二进制
AIart-app/src/assets/img/login_icon.png


二进制
AIart-app/src/assets/img/login_icon2.png


二进制
AIart-app/src/assets/img/login_icon3.png


二进制
AIart-app/src/assets/img/login_icon4.png


二进制
AIart-app/src/assets/img/lunbo1.png


二进制
AIart-app/src/assets/img/lunbo2.png


二进制
AIart-app/src/assets/img/lunbo3.png


二进制
AIart-app/src/assets/img/lunbo4.png


二进制
AIart-app/src/assets/img/next.png


二进制
AIart-app/src/assets/img/prev.png


+ 2 - 2
AIart-app/src/lib/ncloud.ts

@@ -300,7 +300,7 @@ export class CloudObject {
             credentials: "omit"
         });
 
-        const result = await response.json();
+        const result = await response?.json();
         if (result) {
             this.id = null;
         }
@@ -415,4 +415,4 @@ export class CloudQuery {
         }
         return null;
     }
-}
+}

+ 33 - 0
AIart-app/src/lib/user/model-user-edit/model-user-edit.component.html

@@ -0,0 +1,33 @@
+<!-- 用户登录状态 -->
+<ion-card>
+  <ion-card-header>
+    <ion-card-title>
+      用户名:{{currentUser?.get("username")}}
+    </ion-card-title>
+    <ion-card-subtitle>请输入您的详细资料</ion-card-subtitle>
+  </ion-card-header>
+  <ion-card-content>
+
+    <ion-item>
+      <ion-input [value]="userData['realname']" (ionChange)="userDataChange('realname',$event)" label="姓名"
+        placeholder="请您输入真实姓名"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input type="number" [value]="userData['age']" (ionChange)="userDataChange('age',$event)" label="年龄"
+        placeholder="请您输入年龄"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input [value]="userData['gender']" (ionChange)="userDataChange('gender',$event)" label="性别"
+        placeholder="请您输入男/女"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input [value]="userData['avatar']" (ionChange)="userDataChange('avatar',$event)" label="头像"
+        placeholder="请您输入头像地址"></ion-input>
+    </ion-item>
+
+    <ion-button expand="block" (click)="save()">保存</ion-button>
+    <ion-button expand="block" (click)="cancel()">取消</ion-button>
+
+
+  </ion-card-content>
+</ion-card>

+ 0 - 0
AIart-app/src/lib/user/model-user-edit/model-user-edit.component.scss


+ 22 - 0
AIart-app/src/lib/user/model-user-edit/model-user-edit.component.spec.ts

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

+ 63 - 0
AIart-app/src/lib/user/model-user-edit/model-user-edit.component.ts

@@ -0,0 +1,63 @@
+import { Component, OnInit } from '@angular/core';
+import { IonButton, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonContent, IonHeader, IonInput, IonItem, IonLabel, IonSegment, IonSegmentButton, IonTitle, IonToolbar, ModalController } from '@ionic/angular/standalone';
+import { CloudUser } from '../../ncloud';
+
+@Component({
+  selector: 'model-user-edit',
+  templateUrl: './model-user-edit.component.html',
+  styleUrls: ['./model-user-edit.component.scss'],
+  standalone: true,
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardContent,
+    IonButton, IonCardHeader, IonCardTitle, IonCardSubtitle, IonInput, IonItem,
+    IonSegment, IonSegmentButton, IonLabel,
+  ],
+})
+export class ModelUserEditComponent implements OnInit {
+
+  currentUser: CloudUser | undefined
+  userData: any = {}
+  userDataChange(key: string, ev: any) {
+    let value = ev?.detail?.value
+    if (value) {
+      this.userData[key] = value
+    }
+  }
+  constructor(private modalCtrl: ModalController) {
+    this.currentUser = new CloudUser();
+    this.userData = this.currentUser.data;
+  }
+
+  ngOnInit() { }
+
+  async save() {
+    Object.keys(this.userData).forEach(key => {
+      if (key == "age") {
+        this.userData[key] = Number(this.userData[key])
+      }
+    })
+
+    this.currentUser?.set(this.userData)
+    await this.currentUser?.save()
+    this.modalCtrl.dismiss(this.currentUser, "confirm")
+  }
+  cancel() {
+    this.modalCtrl.dismiss(null, "cancel")
+
+  }
+}
+
+export async function openUserEditModal(modalCtrl: ModalController): Promise<CloudUser | null> {
+  const modal = await modalCtrl.create({
+    component: ModelUserEditComponent,
+    breakpoints: [0.7, 1.0],
+    initialBreakpoint: 0.7
+  });
+  modal.present();
+
+  const { data, role } = await modal.onWillDismiss();
+
+  if (role === 'confirm') {
+    return data;
+  }
+  return null
+}

+ 39 - 0
AIart-app/src/lib/user/model-user-login/model-user-login.component.html

@@ -0,0 +1,39 @@
+<!-- 用户登录状态 -->
+<ion-card>
+  <ion-card-header>
+    <ion-card-title>
+      <ion-segment [value]="type" (ionChange)="typeChange($event)">
+        <ion-segment-button value="login">
+          <ion-label>登录</ion-label>
+        </ion-segment-button>
+        <ion-segment-button value="signup">
+          <ion-label>注册</ion-label>
+        </ion-segment-button>
+      </ion-segment>
+    </ion-card-title>
+    <ion-card-subtitle>请输入账号密码</ion-card-subtitle>
+  </ion-card-header>
+  <ion-card-content>
+    <ion-item>
+      <ion-input [value]="username" (ionChange)="usernameChange($event)" label="账号"
+        placeholder="请您输入账号/手机号"></ion-input>
+    </ion-item>
+    <ion-item>
+      <ion-input [value]="password" (ionChange)="passwordChange($event)" label="密码" type="password"
+        value="password"></ion-input>
+    </ion-item>
+
+    @if(type=="signup"){
+    <ion-item>
+      <ion-input [value]="password2" (ionChange)="password2Change($event)" label="重复密码" type="password"
+        value="password"></ion-input>
+    </ion-item>
+    }
+    @if(type=="login"){
+    <ion-button expand="block" (click)="login()">登录</ion-button>
+    }
+    @if(type=="signup"){
+    <ion-button expand="block" (click)="signup()">注册</ion-button>
+    }
+  </ion-card-content>
+</ion-card>

+ 0 - 0
AIart-app/src/lib/user/model-user-login/model-user-login.component.scss


+ 22 - 0
AIart-app/src/lib/user/model-user-login/model-user-login.component.spec.ts

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

+ 91 - 0
AIart-app/src/lib/user/model-user-login/model-user-login.component.ts

@@ -0,0 +1,91 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { IonButton, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonContent, IonHeader, IonInput, IonItem, IonLabel, IonSegment, IonSegmentButton, IonTitle, IonToolbar, ModalController } from '@ionic/angular/standalone';
+import { CloudUser } from '../../ncloud';
+import { ModalUserLoginComponent } from 'fmode-ng';
+
+@Component({
+  selector: 'model-user-login',
+  templateUrl: './model-user-login.component.html',
+  styleUrls: ['./model-user-login.component.scss'],
+  standalone: true,
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardContent,
+    IonButton, IonCardHeader, IonCardTitle, IonCardSubtitle, IonInput, IonItem,
+    IonSegment, IonSegmentButton, IonLabel,
+  ],
+})
+export class ModelUserLoginComponent implements OnInit {
+  @Input()
+  type: "login" | "signup" = "login"
+  typeChange(ev: any) {
+    this.type = ev?.detail?.value || ev?.value || 'login'
+  }
+  username: string = ""
+  usernameChange(ev: any) {
+    console.log(ev)
+    this.username = ev?.detail?.value
+  }
+  password: string = ""
+  passwordChange(ev: any) {
+    this.password = ev?.detail?.value
+  }
+  password2: string = ""
+  password2Change(ev: any) {
+    this.password2 = ev?.detail?.value
+  }
+  constructor(private modalCtrl: ModalController) { }
+
+  ngOnInit() { }
+
+  async login() {
+    if (!this.username || !this.password) {
+      console.log("请输入完整")
+      return
+    }
+    let user: any = new CloudUser();
+    user = await user.login(this.username, this.password);
+    if (user?.id) {
+      this.modalCtrl.dismiss(user, "confirm")
+    } else {
+      console.log("登录失败")
+    }
+  }
+
+  async signup() {
+    if (!this.username || !this.password || !this.password2) {
+      console.log("请输入完整")
+      return
+    }
+    if (this.password != this.password2) {
+      console.log("两次密码不符,请修改")
+      return
+    }
+
+    let user: any = new CloudUser();
+    user = await user.signUp(this.username, this.password);
+    if (user) {
+      this.type = "login"
+      console.log("注册成功请登录")
+    }
+  }
+
+
+}
+
+export async function openUserLoginModal(modalCtrl: ModalController, type: "login" | "signup" = "login"): Promise<CloudUser | null> {
+  const modal = await modalCtrl.create({
+    component: ModelUserLoginComponent,
+    componentProps: {
+      type: type
+    },
+    breakpoints: [0.5, 0.7],
+    initialBreakpoint: 0.5
+  });
+  modal.present();
+
+  const { data, role } = await modal.onWillDismiss();
+
+  if (role === 'confirm') {
+    return data;
+  }
+  return null
+}

+ 569 - 0
AIart-prod/UML Presentation.md

@@ -0,0 +1,569 @@
+# 类图
+```plantuml
+@startuml
+
+class 用户类 {
+    - 用户ID : String
+    - 用户名 : String
+    - 密码 : String
+    - 个人信息 : String
+    - 注册时间 : Date
+    + 注册() : void
+    + 登录() : boolean
+    + 更新个人信息() : void
+    + 提问(String) : void
+    + 分享成果(Result) : void
+}
+
+class 问题类 {
+    - 问题ID : String
+    - 问题描述 : String
+    - 问题选项 : List<String>
+    + 问题修改() : void
+    + 问题查询() : void
+}
+
+class 学习进度类 {
+    - 进度ID : String
+    - 用户 : 用户类
+    - 学习时间 : Date
+    - 学习进度 : double
+    - 学习建议 : String
+    - 学习状态 : String
+    + 记录进度() : void
+    + 获取进度() : String
+    + 提醒学习() : void
+}
+
+class 学习资源类 {
+    - 资源ID : String
+    - 资源类型 : String
+    - 资源名称 : String
+    - 资源内容 : Object
+    + 上传资源() : void
+    + 下载资源() : void
+    + 展示资源() : void
+    + 修改资源() : void
+    + 删除内容() : void
+}
+
+class 社区类 {
+    - 社区ID : String
+    - 社区名称 : String
+    - 社区规则 : String
+    - 帖子 : List<帖子类>
+    + 创建帖子(帖子类) : void
+    + 修改帖子(帖子类) : void
+    + 删除帖子(帖子类) : void
+    + 评论帖子(帖子类, 评论类) : void
+    + 点赞帖子(帖子类) : void
+    + 收藏帖子(帖子类) : void
+}
+
+class 会员类 {
+    - 会员ID : String
+    - 用户 : 用户类
+    - 会员有效期 : Date
+    - 特权信息 : String
+    + 会员注册() : void
+    + 验证会员() : boolean
+    + 会员续费() : void
+}
+
+class 广告类 {
+    - 广告ID : String
+    - 广告内容 : String
+    - 广告投放位置 : String
+    - 投放时间 : Date
+    - 投放目标 : String
+    + 创建广告() : void
+    + 广告投放() : void
+    + 广告效果统计() : void
+}
+
+class 评论类 {
+    - 评论ID : String
+    - 帖子ID : String
+    - 用户ID : String
+    - 点赞数量 : int
+    - 评论内容 : String
+    + 创建评论() : void
+    + 修改评论() : void
+    + 删除评论() : void
+}
+
+class 数据类 {
+    - 数据ID : int
+    - 数据类型 : String
+    - 数据名称 : String
+    - 数据内容 : Object
+    + 数据收集() : void
+    + 数据存储() : void
+    + 数据分析() : void
+    + 数据脱敏() : void
+}
+
+class 帖子类 {
+    - 帖子ID : String
+    - 用户ID : String
+    - 点赞数量 : int
+    - 收藏数量 : int
+    - 评论内容 : List<评论类>
+    - 正文内容 : String
+    + 创建帖子(帖子类) : void
+    + 修改帖子(帖子类) : void
+    + 分享帖子(帖子类) : void
+    + 删除帖子(帖子类) : void
+}
+
+class 测试结果分析类 {
+    - 分析任务ID : String
+    - 分析状态 : String
+    - 分析结果数据 : 数据类
+    - 分析开始时间 : Date
+    - 分析结束时间 : Date
+    + 启动分析() : void
+    + 获取分析结果() : 数据类
+    + 更新分析状态() : void
+    + 重置分析任务() : void
+}
+
+class 兴趣测试类 {
+    - 测试ID : String
+    - 测试问题 : List<问题类>
+    - 测试名称 : String
+    - 所属用户ID : String
+    - 测试创建时间 : Date
+    - 测试状态 : String
+    - 测试结果记录 : String
+    + 开始测试() : void
+    + 收集答案() : void
+    + 获取测试问题() : List<问题类>
+    + 获取所属用户ID() : String
+    + 更新测试状态() : void
+    + 保存测试结果() : void
+}
+
+class 学习资源推荐类 {
+    - 推荐任务ID : String
+    - 目标用户ID : String
+    - 资源推荐列表 : List<学习资源类>
+    - 推荐策略名称 : String
+    - 推荐时间 : Date
+    + 启动推荐() : void
+    + 获取推荐资源列表() : List<学习资源类>
+    + 更新推荐策略() : void
+    + 添加推荐资源() : void
+    + 重置推荐任务() : void
+}
+
+class 学习资源管理类 {
+    - 资源管理任务ID : String
+    - 资源内容 : List<学习资源类>
+    - 资源分类列表 : List<String>
+    - 资源更新时间 : Date
+    - 资源操作日志 : String
+    - 资源索引 : Map<String, 学习资源类>
+    + 修改资源() : void
+    + 删除资源() : void
+    + 添加资源() : void
+    + 查询资源() : List<学习资源类>
+    + 获取资源分类() : List<String>
+    + 查看资源操作日志() : String
+}
+
+class 学习进度跟踪类 {
+    - 跟踪任务ID : String
+    - 关联用户ID : String
+    - 课程学习进度列表 : List<学习进度类>
+    - 进度更新时间 : Date
+    - 学习计划 : String
+    - 进度预警阈值 : int
+    - 预警信息列表 : List<String>
+    + 初始化跟踪() : void
+    + 记录进度() : void
+    + 获取学习进度() : List<课程学习进度类>
+    + 更新学习计划() : void
+    + 获取预警信息() : List<String>
+    + 清除预警信息() : void
+}
+
+class 社区互动类 {
+    - 互动任务ID : String
+    - 社区ID : String
+    - 帖子列表 : List<帖子类>
+    - 用户互动记录 : List<String>
+    - 热门帖子阈值 : int
+    - 热门帖子列表 : List<帖子类>
+    - 互动时间 : Date
+    + 发布帖子() : void
+    + 评论帖子() : void
+    + 点赞帖子() : void
+    + 收藏帖子() : void
+    + 获取帖子列表() : List<帖子类>
+    + 获取热门帖子列表() : List<帖子类>
+    + 获取用户互动记录() : List<String>
+}
+
+class 兴趣测试界面类 {
+    - 界面ID : String
+    - 当前测试任务ID : String
+    - 用户答案列表 : List<String>
+    - 界面状态 : String
+    - 测试开始时间 : Date
+    + 初始化界面() : void
+    + 显示测试问题() : void
+    + 接收用户答案() : void
+    + 提交测试结果() : void
+    + 获取界面状态() : String
+}
+
+class 学习资源推荐展示 {
+    - 展示区域ID : String
+    - 推荐任务ID : String
+    - 资源展示列表 : List<学习资源类>
+    - 用户交互记录 : List<String>
+    - 展示更新时间 : Date
+    + 初始化展示() : void
+    + 更新展示资源() : void
+    + 记录用户交互() : void
+    + 获取展示资源列表() : List<学习资源类>
+}
+
+class 学习资源上传类 {
+    - 任务ID : String
+    - 上传文件列表 : List<学习资源类>
+    - 上传进度列表 : List<Integer>
+    - 上传状态 : String
+    + 初始化上传() : void
+    + 添加上传文件() : void
+    + 开始上传() : void
+    + 暂停上传() : void
+    + 恢复上传() : void
+    + 获取上传进度() : List<Integer>
+    + 获取上传状态() : String
+}
+
+class 学习资源下载类 {
+    - 任务ID : String
+    - 下载资源链接列表 : List<String>
+    - 下载进度列表 : List<Integer>
+    - 下载状态 : String
+    + 初始化下载() : void
+    + 添加下载资源链接() : void
+    + 开始下载() : void
+    + 暂停下载() : void
+    + 恢复下载() : void
+    + 获取下载进度() : List<Integer>
+    + 获取下载状态() : String
+}
+
+class 学习计划展示类 {
+    - 展示ID : String
+    - 关联用户ID : String
+    - 学习计划数据 : List<数据类>
+    - 展示格式 : String
+    - 进度标记列表 : List<学习进度类>
+    - 展示更新时间 : Date
+    + 初始化展示() : void
+    + 更新展示数据() : void
+    + 切换展示格式() : void
+    + 标记学习进度() : void
+    + 获取学习计划数据()
+}
+
+class 社区作品展示与互动 {
+    - 展示区域ID : String
+    - 社区ID : String
+    - 作品列表 : List<帖子类>
+    - 展示排序方式 : String
+    - 用户互动记录 : List<String>
+    - 展示更新时间 : Date
+    + 初始化展示() : void
+    + 更新展示作品() : void
+    + 评论作品() : void
+    + 收藏作品() : void
+    + 获取作品列表() : List<帖子类>
+    + 切换展示排序() : void
+}
+
+'聚合关系
+用户类 "1" *-- "0..*" 学习进度类
+用户类 "1" *-- "0..*" 帖子类
+用户类 "1" *-- "0..*" 评论类
+用户类 "1" *-- "0..*" 会员类
+问题类 "1" *-- "0..*" 兴趣测试类
+学习资源类 "1" *-- "0..*" 学习资源管理类
+学习资源类 "1" *-- "0..*" 学习资源推荐类
+帖子类 "1" *-- "0..*" 社区类
+帖子类 "1" *-- "0..*" 社区互动类
+评论类 "1" *-- "0..*" 帖子类
+
+'组合关系
+学习进度跟踪类 "1" -- "0..*" 学习进度类 : 包含
+社区互动类 "1" -- "0..*" 帖子类 : 包含
+社区互动类 "1" -- "0..*" 评论类 : 包含
+学习资源上传类 "1" -- "0..*" 学习资源类 : 包含
+学习资源下载类 "1" -- "0..*" 学习资源类 : 包含
+学习计划展示类 "1" -- "0..*" 数据类 : 包含
+学习计划展示类 "1" -- "0..*" 学习进度类 : 包含
+
+@enduml
+```
+
+
+# 时序图
+
+## 一、用户参与兴趣测试并获取结果时序图
+```plantuml
+@startuml
+actor 用户
+boundary 兴趣测试界面
+control 兴趣测试
+control 测试结果分析层
+
+用户 -> 兴趣测试界面: 请求开始测试
+兴趣测试界面 -> 兴趣测试界面: 初始化界面()
+兴趣测试界面 -> 兴趣测试: 获取测试问题()
+兴趣测试 -> 兴趣测试界面: 返回测试问题列表
+兴趣测试界面 -> 兴趣测试界面: 显示测试问题()
+用户 -> 兴趣测试界面: 回答问题
+兴趣测试界面 -> 兴趣测试界面: 接收用户答案()
+兴趣测试界面 -> 兴趣测试: 收集答案()
+兴趣测试 -> 兴趣测试: 更新测试状态()
+兴趣测试 -> 兴趣测试界面: 提示已完成所有问题回答
+兴趣测试界面 -> 测试结果分析层: 提交测试结果()
+测试结果分析层 -> 测试结果分析层: 启动分析()
+测试结果分析层 -> 测试结果分析层: 获取分析结果()
+测试结果分析层 -> 兴趣测试: 保存测试结果()
+兴趣测试 -> 兴趣测试界面: 显示测试结果
+兴趣测试界面 -> 用户: 展示测试结果
+@enduml
+```
+## 二、学习资源推荐给用户的时序图
+```plantuml
+@startuml
+actor 用户
+control 学习资源推荐
+boundary 学习资源推荐展示
+
+用户 -> 学习资源推荐: 进入学习页面(触发推荐)
+学习资源推荐 -> 学习资源推荐: 启动推荐()
+学习资源推荐 -> 学习资源推荐: 获取推荐资源列表()
+学习资源推荐 -> 学习资源推荐展示: 传递推荐资源列表
+学习资源推荐展示 -> 学习资源推荐展示: 初始化展示()
+学习资源推荐展示 -> 用户: 展示推荐资源
+用户 -> 学习资源推荐展示: 与推荐资源交互(如点击查看详情等)
+学习资源推荐展示 -> 学习资源推荐展示: 记录用户交互()
+@enduml
+```
+## 三、用户上传学习资源的时序图
+```plantuml
+@startuml
+actor 用户
+boundary 学习资源上传
+control 学习资源管理
+
+用户 -> 学习资源上传: 选择要上传的资源
+学习资源上传 -> 学习资源上传: 初始化上传()
+学习资源上传 -> 学习资源上传: 添加上传文件()
+学习资源上传 -> 学习资源管理: 开始上传()
+学习资源管理 -> 学习资源管理: 添加资源()
+学习资源管理 -> 学习资源上传: 返回上传进度及状态更新
+学习资源上传 -> 学习资源上传: 更新上传进度显示
+学习资源上传 -> 用户: 展示上传进度
+学习资源管理 -> 学习资源上传: 上传完成通知
+学习资源上传 -> 用户: 提示上传成功
+@enduml
+```
+## 四、用户在社区发布帖子及互动的时序图
+```plantuml
+@startuml
+actor 用户
+boundary 社区作品展示与互动
+control 社区互动
+
+用户 -> 社区作品展示与互动: 编写帖子内容并点击发布
+社区作品展示与互动 -> 社区互动: 发布帖子()
+社区互动 -> 社区互动: 添加帖子到帖子列表
+社区互动 -> 社区作品展示与互动: 返回发布成功及更新后的帖子列表
+社区作品展示与互动 -> 社区作品展示与互动: 更新展示作品()
+社区作品展示与互动 -> 社区作品展示与互动: 展示新发布的帖子
+用户 -> 社区作品展示与互动: 对帖子进行点赞操作
+社区作品展示与互动 -> 社区互动: 点赞帖子()
+社区互动 -> 社区互动: 更新帖子点赞数及热门帖子列表(若满足条件)
+社区互动 -> 社区作品展示与互动: 返回更新后的点赞数等信息
+社区作品展示与互动 -> 社区作品展示与互动: 更新展示点赞数
+@enduml
+```
+
+## 五、学习计划展示时序图
+```plantuml
+@startuml
+actor 用户
+boundary 学习计划展示
+control 学习进度跟踪
+
+用户 -> 学习计划展示: 进入学习计划展示页面
+学习计划展示 -> 学习计划展示: 初始化展示()
+学习计划展示 -> 学习进度跟踪: 请求获取学习计划数据
+学习进度跟踪 -> 学习进度跟踪: 获取学习计划数据()
+学习进度跟踪 -> 学习计划展示: 返回学习计划数据
+学习计划展示 -> 学习计划展示: 更新展示数据()
+学习计划展示 -> 用户: 展示学习计划详情(含进度标记等)
+用户 -> 学习计划展示: 完成部分学习任务,触发进度更新
+学习计划展示 -> 学习计划展示: 标记学习进度()
+学习计划展示 -> 学习进度跟踪: 传递进度更新信息
+学习进度跟踪 -> 学习进度跟踪: 更新学习计划相关信息
+学习进度跟踪 -> 学习计划展示: 返回更新后的学习计划数据
+学习计划展示 -> 学习计划展示: 更新展示数据()
+学习计划展示 -> 用户: 展示更新后的学习计划详情
+@enduml
+```
+
+## 六、学习资源下载时序图
+```plantuml
+@startuml
+actor 用户
+boundary 学习资源下载
+control 学习资源管理
+
+用户 -> 学习资源下载: 选择要下载的资源
+学习资源下载 -> 学习资源下载: 初始化下载()
+学习资源下载 -> 学习资源下载: 添加下载资源链接()
+学习资源下载 -> 学习资源管理: 开始下载()
+学习资源管理 -> 学习资源管理: 准备下载资源(验证权限等)
+学习资源管理 -> 学习资源下载: 返回下载进度更新信息
+学习资源下载 -> 学习资源下载: 更新下载进度显示
+学习资源下载 -> 用户: 展示下载进度
+学习资源管理 -> 学习资源下载: 下载完成通知
+学习资源下载 -> 用户: 提示下载成功并提供资源保存路径(或自动打开等操作)
+@enduml
+```
+# 状态图
+## (一)用户登录状态图
+
+```plantuml
+@startuml
+[*] --> 未登录
+未登录 --> 登录中 : 用户输入用户名和密码,点击登录按钮
+登录中 --> 已登录 : 验证通过
+登录中 --> 未登录 : 验证失败(用户名或密码错误等)
+已登录 --> 已注销 : 用户点击注销按钮
+已注销 --> 未登录
+@enduml
+```
+ 
+
+(二)学习资源状态图
+```plantuml
+@startuml
+[*] --> 资源未上传
+资源未上传 --> 资源上传中 : 用户发起资源上传操作
+资源上传中 --> 资源已上传 : 上传完成
+资源上传中 --> 资源未上传 : 上传失败(网络问题、权限不足等)
+资源已上传 --> 资源展示中 : 符合展示条件,被推荐展示
+资源展示中 --> 资源已删除 : 执行删除操作
+资源已删除 --> 资源未上传
+资源已上传 --> 资源修改中 : 用户发起资源修改操作
+资源修改中 --> 资源已上传 : 修改完成
+资源修改中 --> 资源已上传 : 修改失败(格式不符、权限问题等)
+@enduml
+```
+
+(三)帖子状态图
+
+```plantuml
+@startuml
+[*] --> 帖子未发布
+帖子未发布 --> 帖子发布中 : 用户编写内容,点击发布按钮
+帖子发布中 --> 帖子已发布 : 发布成功
+帖子发布中 --> 帖子未发布 : 发布失败(违反社区规则、系统故障等)
+帖子已发布 --> 帖子正常 : 无异常情况
+帖子正常 --> 帖子被修改 : 用户发起修改操作
+帖子被修改 --> 帖子正常 : 修改完成
+帖子正常 --> 帖子被删除 : 用户或管理员执行删除操作
+帖子被删除 --> 帖子未发布
+帖子正常 --> 帖子热门 : 满足热门条件(点赞、评论等达到阈值)
+帖子热门 --> 帖子正常 : 热度下降,不再满足热门条件
+@enduml
+```
+
+# 活动图
+## (一)用户参与兴趣测试活动图
+
+
+```plantuml
+@startuml
+start
+:用户进入兴趣测试界面;
+:初始化界面;
+:请求获取测试问题;
+:返回测试问题列表;
+:显示测试问题;
+while (所有问题回答完毕) is (true)
+:用户->兴趣测试界面类: 回答问题;
+    :接收用户答案;
+    :传递用户答案,收集答案;
+end while 
+:更新测试状态;
+:提交测试结果;
+:传递结果,请求启动分析;
+:启动分析;
+:获取分析结果;
+:返回分析结果;
+:保存测试结果;
+:通知展示测试结果;
+:展示测试结果;
+stop
+@enduml
+```
+
+
+## (二)用户上传学习资源活动图
+```plantuml
+@startuml
+start
+:用户选择要上传的学习资源;
+:初始化上传;
+:添加上传文件;
+:开始上传;
+while (上传未完成) is (true)
+    :获取上传进度;
+    :更新上传进度显示;
+end while
+:获取上传状态;
+if (上传成功) then (true)
+    :提示用户上传成功;
+else (false)
+    :提示用户上传失败及原因;
+endif
+stop
+@enduml
+```
+## (三)用户在社区发布并互动帖子活动图
+
+```plantuml
+@startuml
+start
+:用户进入社区,编写帖子内容;
+:发布帖子;
+:创建帖子;
+:获取帖子列表;
+:更新展示作品;
+:展示帖子列表给用户;
+while (用户进行互动操作) is (true)
+    if (用户点赞帖子) then (true)
+        :点赞帖子;
+    else if (用户评论帖子) then (true)
+        :评论帖子;
+    else if (用户收藏帖子) then (true)
+        :收藏帖子;
+    endif
+    :获取热门帖子列表;
+    :更新展示作品;
+    :展示更新后的帖子列表给用户;
+end while
+stop
+@enduml
+```

+ 108 - 1
AIart-prod/communitySharing.md

@@ -408,4 +408,111 @@ participant "评论表" as 评论数据库
 
 用户在作品展示页面加载所有作品,系统从数据库获取数据并展示。
 用户可以浏览作品详情,进行点赞和评论操作。
-系统在用户进行互动后,更新相应的数据,并评估哪些作品是热门作品。
+系统在用户进行互动后,更新相应的数据,并评估哪些作品是热门作品。
+
+
+```plantuml
+@startuml
+class University {
+    - String name
+    + void manageColleges()
+}
+
+class College {
+    - String collegeName
+    + void manageDepartments()
+    + void manageClasses()
+}
+
+class Department {
+    - String departmentName
+    + void arrangeTeachers()
+}
+
+class Teacher {
+    - String teacherName
+    - int teacherId
+    + void teachCourses()
+    + void assignTeachingTasks()
+}
+
+class Student {
+    - String studentName
+    - int studentId
+    + void selectCourses()
+    + void attendClasses()
+}
+
+class UndergraduateStudent extends Student {
+    - String major
+}
+
+class GraduateStudent extends Student {
+    - String researchDirection
+}
+
+class Course {
+    - String courseName
+    - int courseId
+    + void setCourseContent()
+}
+
+class TeachingTask {
+    - int taskId
+    + void setTaskDetails()
+}
+
+University "1" *-- "n" College
+College "1" *-- "n" Department
+College "1" *-- "n" Class
+Department "1" *-- "n" Teacher
+Student "1" <|-- "n" UndergraduateStudent
+Student "1" <|-- "n" GraduateStudent
+Teacher "1" *-- "n" TeachingTask
+Teacher "1" *-- "n" Course
+Student "n" *-- "m" Course
+@enduml
+```
+
+
+```plantuml
+@startuml
+title 大学教务管理系统选课顺序图
+
+actor Student as s
+participant Undergraduate as ug
+participant Graduate as gr
+participant Class as c
+participant College as col
+participant TeachingAndResearchOffice as tro
+participant Teacher as t
+participant Course as co
+participant TeachingTask as tt
+
+s -> ug: 是本科生\n请求选课
+s -> gr: 是研究生\n请求选课
+
+ug -> c: 查询可选课程
+gr -> c: 查询可选课程
+
+c -> col: 传递课程查询请求
+col -> tro: 请求获取授课教师及课程信息
+tro -> t: 查询授课教师\n获取课程信息
+t -> tt: 查看教学任务相关课程
+tt -> co: 获取课程详情
+
+co -> c: 返回课程详情
+c -> ug: 返回可选课程信息
+c -> gr: 返回可选课程信息
+
+ug -> co: 选择课程
+gr -> co: 选择课程
+
+co -> tt: 记录选课信息
+tt -> t: 通知教师选课情况
+t -> tro: 反馈选课情况至教研室
+tro -> col: 反馈至学院
+col -> c: 班级内更新选课状态
+c -> ug: 确认选课成功
+c -> gr: 确认选课成功
+@enduml

+ 0 - 23
AIart-prod/text.md

@@ -1,23 +0,0 @@
-# 项目名称
-```plantuml
-@startuml
-abstract        abstract
-abstract class  "abstract class"
-annotation      annotation
-circle          circle
-()              circle_short_form
-class           class
-class           class_stereo  <<stereotype>>
-diamond         diamond
-<>              diamond_short_form
-entity          entity
-enum            enum
-exception       exception
-interface       interface
-metaclass       metaclass
-protocol        protocol
-stereotype      stereotype
-struct          struct
-@enduml
-```
-# 类型设置