瀏覽代碼

Merge branch 'master' of http://git.fmode.cn:3000/lzy/S202226701025

yi 1 年之前
父節點
當前提交
0436907927

文件差異過大導致無法顯示
+ 1245 - 198
FilmDraw-app/package-lock.json


+ 9 - 0
FilmDraw-app/package.json

@@ -27,8 +27,17 @@
     "@capacitor/keyboard": "6.0.3",
     "@capacitor/status-bar": "6.0.2",
     "@ionic/angular": "^8.0.0",
+    "@langchain/community": "^0.3.19",
+    "@langchain/core": "^0.3.26",
+    "@tensorflow-models/universal-sentence-encoder": "^1.3.3",
+    "@tensorflow/tfjs-backend-cpu": "^4.22.0",
+    "@tensorflow/tfjs-backend-webgl": "^4.22.0",
+    "@tensorflow/tfjs-converter": "^4.22.0",
+    "@tensorflow/tfjs-core": "^4.22.0",
     "fmode-ng": "^0.0.63",
     "ionicons": "^7.2.1",
+    "langchain": "^0.3.7",
+    "mammoth": "^1.8.0",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",
     "zone.js": "~0.14.2"

+ 9 - 5
FilmDraw-app/src/app/tab1/tab1.page.html

@@ -1,17 +1,21 @@
 <ion-header [translucent]="true">
   <ion-toolbar>
     <ion-item lines="none">
-      <!-- 图片 -->
-        <ion-avatar slot="start" class="image-container">
-            <img src="/assets/img/1.png" alt="Your Image" class="header-image">
+      <ion-avatar slot="start" class="image-container">
+        <img src="/assets/img/1.png" alt="Your Image" class="header-image">
       </ion-avatar>
-      <!-- 搜索框 -->
       <ion-searchbar slot="end" expand="with-icon"></ion-searchbar>
+      <ion-buttons slot="end">
+        <ion-button (click)="openPublishModal()">
+            发布+ 
+        </ion-button>
+      </ion-buttons>
     </ion-item>
   </ion-toolbar>
 </ion-header>
- <ion-content [fullscreen]="true">
 
+
+ <ion-content [fullscreen]="true">
 <!-- 包含热门话题区和讨论区的父容器 -->
 
   <div class="content-container">

+ 15 - 0
FilmDraw-app/src/app/tab1/tab1.page.scss

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 // ion-toolbar {
 //   display: flex;
 //   justify-content: space-between; // 使内容在两侧分开
@@ -28,6 +29,8 @@
 
 
 
+=======
+>>>>>>> fe70b786df2f8f475ffdf23a041efd136b02587f
 .content-container {
   display: flex;
   justify-content: space-between; /* 在主轴上均匀分配空间 */
@@ -75,12 +78,24 @@ ion-label p {
   font-size: 0.9em; /* 字体大小 */
 }
 
+/* 设置搜索框的样式 */
+   ion-searchbar {
+     padding: 10px; /* 内边距 */
+     border-radius: 6px; /* 圆角 */
+     font-size: 16px; /* 字体大小 */
+    }
 
+<<<<<<< HEAD
 
 // ion-header {
 //     background-color: #ffffff; // 设置头部背景色
 //     color: white; // 设置头部文字颜色
 //   }
+=======
+ion-header {
+    background-color: #f5f7fc; // 设置头部背景色
+  }
+>>>>>>> fe70b786df2f8f475ffdf23a041efd136b02587f
   
 //   ion-card {
 //     margin: 10px; // 设置卡片之间的间距

+ 23 - 1
FilmDraw-app/src/app/tab1/tab1.page.ts

@@ -2,9 +2,13 @@ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
 import { 
   IonHeader, IonToolbar, IonTitle, IonContent, 
   IonButton, IonButtons, IonIcon, IonCard, IonCardHeader, IonCardTitle, IonCardContent,
-  IonItem, IonLabel, IonList, IonInput, IonTextarea, IonAvatar, IonSearchbar} from '@ionic/angular/standalone';
+  IonItem, IonLabel, IonList, IonInput, IonTextarea, IonAvatar, IonSearchbar,
+  ModalController} from '@ionic/angular/standalone';
 import { ExploreContainerComponent } from '../explore-container/explore-container.component';
 import { CommonModule } from '@angular/common';
+import { openPostPublisherModal } from 'src/lib/public/post-publisher/post-publisher.component';
+import { CloudUser } from 'src/lib/ncloud';
+import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
 
 @Component({
   selector: 'app-tab1',
@@ -23,7 +27,25 @@ import { CommonModule } from '@angular/common';
   schemas: [CUSTOM_ELEMENTS_SCHEMA], 
 })
 export class Tab1Page {
+  currentUser:CloudUser|undefined
+  constructor(private modalCtrl:ModalController){
+    this.currentUser=new CloudUser();
+  }
+
+
+async openPublishModal(){
+
+
+  if(!this.currentUser?.id){
+    openUserLoginModal(this.modalCtrl);
+  }
+if(this.currentUser){
+  openPostPublisherModal(this.modalCtrl);
+}
   
+
+}
+
   onSearch(event: any) {
         const searchTerm = event.target.value; // 获取用户输入的搜索内容
         console.log('搜索内容:', searchTerm);

+ 4 - 4
FilmDraw-app/src/app/tab3/tab3.page.html

@@ -6,7 +6,7 @@
 
 <ion-content [fullscreen]="true">
   <!-- AI陪聊搭子区域 -->
-    <section>
+    <section id="one">
       <ion-card>
         <ion-card-header>
           <ion-card-title>AI陪聊搭子</ion-card-title>
@@ -15,7 +15,7 @@
           <ion-list>
             <ion-item *ngFor="let filmpartner of filmpartnerList" lines="none">
               <ion-thumbnail slot="start">
-                <img [src]="filmpartner.get('avatar')" [alt]="filmpartner.get('name')" />
+                <img [src]="filmpartner.get('avatar')" />
               </ion-thumbnail>
               <div class="filmpartner-info">
                 <h3>{{ filmpartner.get('name') }}({{ filmpartner.get('age') }}岁)</h3>
@@ -31,7 +31,7 @@
 
 
   <!-- 角色互动区域 -->
-  <section>
+  <section id="two">
     <ion-card>
       <ion-card-header>
         <ion-card-title>角色互动</ion-card-title>
@@ -40,7 +40,7 @@
         <ion-list>
     <ion-item *ngFor="let filmrole of filmroleList" lines="none">
       <ion-thumbnail slot="start">
-        <img [src]="filmrole.get('avatar')" [alt]="filmrole.get('name')" />
+        <img [src]="filmrole.get('avatar')" />
       </ion-thumbnail>
       <div class="filmpartner-info">
         <h3>{{ filmrole.get('name') }}</h3>

+ 124 - 98
FilmDraw-app/src/app/tab3/tab3.page.scss

@@ -1,118 +1,144 @@
+// 定义颜色变量
+$light-blue: #e0f7fa;
+$blue: #bbdcff;
+$dark-blue: #587fb6;
+$text-color: #333;
+
 ion-title {
   flex: 1; // 使标题占据可用空间
   text-align: left; // 确保文字左对齐
   margin-left: 16px; // 左侧边距,可以根据需要调整
   margin-top: 5px;
-  color: rgb(71, 68, 68);
-}
+  // font-family: 楷体;
+  // font-style: italic;
+  }
 
 ion-header {
-  background-color: #3880ff; // 设置头部背景色
-}
-
-
-ion-card {
-  margin: 10px; // 设置卡片之间的间距
-  border-radius: 10px; // 设置卡片圆角
-  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); // 添加阴影效果
-}
-
-ion-card-header {
-  background-color: #d8e5fa; // 设置头部背景色
+  background-color: #f5f7fc; // 设置头部背景色
   color: white; // 设置头部文字颜色
 }
 
-ion-card-title {
-  font-size: 1.2em; // 设置卡片标题字体大小
-  font-weight: bold; // 设置卡片标题字体加粗
-}
-
-ion-item {
-  --ion-item-background: transparent; // 设置列表项背景透明
+ion-content {
+  background-color: #f9f9f9; // 内容背景颜色
 }
 
-ion-label {
-  color: #333; // 设置标签文字颜色
-}
-
-
-
-h2 {
-  font-size: 1em; // 设置二级标题字体大小
-  margin: 0; // 去掉默认外边距
-}
-
-p {
-  font-size: 0.9em; // 设置段落字体大小
-  color: #666; // 设置段落文字颜色
-}
-
-ion-list {
-  padding: 0; // 去掉列表内边距
-}
-
-ion-card-content {
-  padding: 10px; // 设置卡片内容内边距
-}
-
-ion-button {
-  --background: #3880ff; // 设置按钮背景色
-  --color: white; // 设置按钮文字颜色
-  margin-top: 10px; // 设置按钮与上方内容的间距
-  border-radius: 20px; // 设置按钮圆角
-}
-
-
-.chat-partner-area {
-  display: flex;
-  align-items: center;
-  margin-bottom: 20px;
-  border: 1px solid #ccc;
-  border-radius: 10px;
-  padding: 15px;
-
-  .avatar {
-    width: 60px;
-    height: 60px;
-    border-radius: 50%;
-    margin-right: 15px;
-  }
-
-  .description {
-    flex-grow: 1;
-  }
+// AI陪聊搭子区域样式
+#one {
+  margin: 15px;
+
+  ion-card {
+    background-color: white;
+    border-radius: 8px;
+    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+    
+    ion-card-header {
+      background-color: $blue;
+      ion-card-title {
+        color: rgb(37, 37, 37);
+        font-size: 1.5rem;
+      }
+    }
 
-  ion-button {
-    border-radius: 20px;
+    ion-card-content {
+      ion-list {
+        ion-item {
+          display: flex;
+          align-items: center;
+          margin-top: 15px;
+
+          ion-thumbnail {
+            margin-right: 16px;
+            img {
+              border-radius: 50%;
+              width: 50px;
+              height: 50px;
+            }
+          }
+
+          .filmpartner-info {
+            flex: 1;
+            h3 {
+              color: $dark-blue;
+              margin: 4px 0 0 0 0;
+              font-size: 1.1rem;
+            }
+            p {
+              color: $text-color;
+              margin: 6px 0;
+            }
+          }
+
+          ion-button {
+            background-color: $blue;
+            color: white;
+            border-radius: 20px;
+            &:hover {
+              background-color: darken($blue, 10%);
+            }
+            
+          }
+        }
+      }
+    }
   }
 }
 
-.role-interaction-area {
-  h2 {
-    margin-bottom: 15px;
-  }
-
-  .role-container {
-    display: flex;
-    align-items: center;
-    margin-bottom: 15px;
-    border: 1px solid #ccc;
-    border-radius: 10px;
-    padding: 15px;
-
-    .avatar {
-      width: 50px;
-      height: 50px;
-      border-radius: 50%;
-      margin-right: 10px;
-    }
-
-    .role-description {
-      flex-grow: 1;
+// 角色互动区域样式
+#two {
+  margin: 15px;
+
+  ion-card {
+    background-color: white;
+    border-radius: 8px;
+    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+    
+    ion-card-header {
+      background-color: $blue;
+      ion-card-title {
+        color: rgb(37, 37, 37);
+        font-size: 1.5rem;
+      }
     }
 
-    ion-button {
-      border-radius: 20px;
+    ion-card-content {
+      ion-list {
+        ion-item {
+          margin-top: 15px;
+          display: flex;
+          align-items: center;
+
+          ion-thumbnail {
+            margin-right: 16px;
+            img {
+              border-radius: 50%;
+              width: 50px;
+              height: 50px;
+            }
+          }
+
+          .filmpartner-info {
+            flex: 1;
+            h3 {
+              color: $dark-blue;
+              margin: 0;
+              font-size: 1.1rem;
+            }
+            p {
+              color: $text-color;
+              margin: 6px 0;
+            }
+          }
+
+          ion-button {
+            background-color: $blue;
+            color: white;
+            border-radius: 20px;
+            &:hover {
+              background-color: darken($blue, 10%);
+            }
+          }
+        }
+      }
     }
   }
-}
+}

+ 17 - 1
FilmDraw-app/src/app/tab4/tab4.page.scss

@@ -1,4 +1,4 @@
-  /* 全局样式 */
+/* 全局样式 */
   body {
     font-family: Arial, sans-serif;
     margin: 0;
@@ -6,6 +6,22 @@
     background-color: #f4f4f4;
   }
  
+  ion-title {
+    flex: 1; // 使标题占据可用空间
+    text-align: left; // 确保文字左对齐
+    margin-left: 16px; // 左侧边距,可以根据需要调整
+    margin-top: 5px;
+  }
+  
+  ion-header {
+    background-color: #f5f7fc; // 设置头部背景色
+    color: white; // 设置头部文字颜色
+  }
+  
+  ion-content {
+    background-color: #f9f9f9; // 内容背景颜色
+  }
+
   ion-content {
     padding: 20px;
   }

+ 1 - 1
FilmDraw-app/src/app/tab4/tab4.page.ts

@@ -30,7 +30,7 @@ export class Tab4Page {
     username: 'yi',
     // 其他用户信息字段...
   };
-  avatarUrl: string = 'assets/img/tx.jpg'; // 默认头像路径
+  avatarUrl: string = 'assets/img/1.png'; // 默认头像路径
  
   currentUser:CloudUser|undefined
   constructor(private modalCtrl:ModalController, private navCtrl: NavController) {

二進制
FilmDraw-app/src/assets/img/2.png


二進制
FilmDraw-app/src/assets/img/3.png


二進制
FilmDraw-app/src/assets/img/4.png


二進制
FilmDraw-app/src/assets/img/5.png


二進制
FilmDraw-app/src/assets/img/tx.png


+ 21 - 0
FilmDraw-app/src/lib/ncloud.ts

@@ -372,7 +372,28 @@ export class CloudUser extends CloudObject {
         localStorage.setItem("NCloud/dev/User",JSON.stringify(this.data))
         return this;
     }
+}
 
+//CloudPost.ts
+export class CloudPost extends CloudObject {
+    constructor() {
+        super('FilmPosts'); // 调用父类构造函数,指定类名
+    }
 
+    // 设置帖子数据,包括发布者信息
+    setPostData(postData: Record<string, any>, userId: string) {
+        this.set(postData); // 设置帖子内容
+        this.data["author"] = { "__type": "Pointer", "className": "_User", "objectId": userId }; // 设置发布者信息
+    }
 
+    // 更新帖子数据
+    async updatePost(postData: Record<string, any>) {
+        this.set(postData); // 更新帖子内容
+        return await this.save(); // 保存更新
+    }
+
+    // 删除帖子
+    async deletePost() {
+        return await this.destroy(); // 调用父类的 destroy 方法
+    }
 }

+ 23 - 0
FilmDraw-app/src/lib/public/post-publisher/post-publisher.component.html

@@ -0,0 +1,23 @@
+<!-- 发布帖子 -->
+<ion-card>
+  <ion-card-header>
+    <ion-card-title>
+      发布
+    </ion-card-title>
+    <ion-card-subtitle>分享新鲜事</ion-card-subtitle>
+   </ion-card-header>
+ <ion-card-content>
+
+   <ion-item>
+     <ion-input [value]="postData['content']" (ionChange)="postDataChange('content',$event)" label="内容" placeholder="请输入你要分享的内容"></ion-input>
+   </ion-item>
+   <ion-item>
+    <ion-input [value]="postData['label']" (ionChange)="postDataChange('label',$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
FilmDraw-app/src/lib/public/post-publisher/post-publisher.component.scss


+ 22 - 0
FilmDraw-app/src/lib/public/post-publisher/post-publisher.component.spec.ts

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

+ 67 - 0
FilmDraw-app/src/lib/public/post-publisher/post-publisher.component.ts

@@ -0,0 +1,67 @@
+import { Component, OnInit } from '@angular/core';
+import { IonHeader, IonToolbar, IonTitle, IonContent, IonCard, IonCardContent, IonButton, 
+  IonCardHeader, IonCardTitle, IonCardSubtitle, ModalController, IonInput, IonItem, 
+  IonSegment, IonSegmentButton, IonLabel } from '@ionic/angular/standalone';
+import { CloudPost, CloudUser } from 'src/lib/ncloud';
+@Component({
+  selector: 'app-post-publisher',
+  templateUrl: './post-publisher.component.html',
+  styleUrls: ['./post-publisher.component.scss'],
+  standalone: true,
+  imports: [IonHeader, IonToolbar, IonTitle, IonContent, 
+    IonCard,IonCardContent,IonButton,IonCardHeader,IonCardTitle,IonCardSubtitle,
+    IonInput,IonItem,
+    IonSegment,IonSegmentButton,IonLabel
+  ],
+})
+export class PostPublisherComponent  implements OnInit {
+ 
+
+  postData:any={
+
+  }
+  userId: string; // 当前用户ID
+  postDataChange(key:string,env:any){
+    this.postData[key] = env.detail.value; // 更新 postData 对象
+ 
+  }
+
+  constructor(private modalCtrl:ModalController) { 
+    this.userId = 'currentUserId';
+  }
+
+  async save(){
+    const post = new CloudPost();
+    post.setPostData(this.postData, this.userId); // 设置帖子数据和用户ID
+
+    try {
+      await post.save(); // 保存帖子
+      this.modalCtrl.dismiss(); // 保存成功后关闭模态框
+    } catch (error) {
+      console.error('保存帖子失败:', error);
+    }
+
+  }
+  cancel(){
+    this.modalCtrl.dismiss(null,"cancel")// 关闭模态框
+
+  }
+
+  ngOnInit() {}
+
+}
+export async function openPostPublisherModal(modalCtrl:ModalController):Promise<CloudUser|null>{
+  const modal = await modalCtrl.create({
+    component: PostPublisherComponent,
+    breakpoints:[0.8,1.0],
+    initialBreakpoint:0.7
+  });
+  modal.present();
+
+  const { data, role } = await modal.onWillDismiss();
+
+  if (role === 'confirm') {
+    return data;
+  }
+  return null
+}

+ 7 - 2
FilmDraw-prod/UML.md

@@ -7,8 +7,10 @@
 1._User表
 objectId: String (默认)
 createdAt: Date (默认)
+userId:String
 age: Number
 gender: String
+avatar:String
 watchHistory: Array<Pointer>
 ratingHistory: Array<Pointer>
 
@@ -98,10 +100,13 @@ objectId: String (默认)
 createdAt: Date (默认)
 user: Pointer
 content: String
+label:String(话题)
 likesCount: Number
-commentsCount: Number
-status: String (例如 "pending", "approved", "rejected")
+status: String (例如 "pending", "approved", "rejected",默认为通过)
+
+
 
+comments:Pointer
 3.FilmComment表
 objectId: String (默认)
 createdAt: Date (默认)

部分文件因文件數量過多而無法顯示