Browse Source

feat:new sendpost

15207938132 2 months ago
parent
commit
74f10cd459

+ 4 - 0
fashion-app/src/app/app.routes.ts

@@ -1,6 +1,10 @@
 import { Routes } from '@angular/router';
 
 export const routes: Routes = [
+  { path: 'sendpost',
+    loadComponent: () =>
+      import('./send-post/send-post.component').then((m) => m.SendPostComponent),
+  },
   {
     path: '',
     loadChildren: () => import('./tabs/tabs.routes').then((m) => m.routes),

+ 60 - 0
fashion-app/src/app/send-post/send-post.component.html

@@ -0,0 +1,60 @@
+<ion-header >
+  <ion-toolbar class="head">
+    <ion-buttons slot="start">
+      <ion-button (click)="goBack()">
+        <ion-icon name="chevron-back-sharp" style="color: black; font-size:30px"></ion-icon>
+      </ion-button>
+    </ion-buttons>
+    <ion-title style="font-size: 20px;">发布帖子</ion-title>
+<ion-buttons slot="end">
+      <ion-button class="publish-button" color="black"
+        [ngClass]="{'active': inputText.length > 0 && remainingChars<20}" 
+        (click)="publishPost()" [disabled]="inputText.length === 0 || remainingChars < 0"> <!-- 禁用条件 -->
+        发布
+      </ion-button>
+</ion-buttons>
+
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <div class="input-area">
+    <div class="title-input">
+      <ion-input 
+        [(ngModel)]="title" 
+        placeholder="添加标题" 
+        maxlength="20" 
+        (ionInput)="updateTitleLength()">
+      </ion-input>
+      <span class="char-counter">{{ remainingChars }} </span>
+    </div>
+    <ion-textarea 
+      [(ngModel)]="inputText" 
+      placeholder="分享你的穿搭..." >
+    </ion-textarea>
+  </div>
+</ion-content>
+
+<ion-footer class="footer">
+  <div class="left-icons">
+    <div class="footer-button" (click)="uploadImage()">
+      <ion-icon name="image-outline"></ion-icon>
+    </div>
+    <div fill="clear"class="footer-button">
+      <ion-icon name="at-outline"></ion-icon>
+    </div>
+    <div fill="clear" class="footer-button">
+      <ion-icon name="happy-outline"></ion-icon>
+    </div>
+  </div>
+  <div class="location-tag" (click)="removeLocationTag()" *ngIf="showLocationTag">
+  
+      <ion-icon name="pin"></ion-icon>
+      <span >南昌市</span>
+      <ion-icon name="close-outline" slot="end"></ion-icon>
+
+  </div>
+
+  <!-- 隐藏的文件输入 -->
+  <input type="file" accept="image/*" (change)="onFileSelected($event)" style="display: none;" #fileInput>
+</ion-footer>

+ 87 - 0
fashion-app/src/app/send-post/send-post.component.scss

@@ -0,0 +1,87 @@
+//头部区域
+.head{
+    height:70px;
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: center; 
+
+}
+
+//发布按钮
+.publish-button {
+    height: 35px;
+    width: 70px;
+    background-color: rgb(236, 235, 233); /* 橙色背景 */
+    color: gray ; /* 强制设置文字颜色为白色 */
+    border-radius: 20px; /* 椭圆形 */
+    font-size: 16px; /* 调整字体大小 */
+
+  
+    &.active {
+      /* 当输入框有内容时的样式 */
+      background-color: white; /* 背景色变为黑色 */
+      color: black; /* 字体颜色变为白色 */
+    }
+  }
+  
+  .input-area {
+    height: 670px; /* 设置输入区域的高度 */
+    padding: 10px; /* 设置内边距 */
+    font-size: 18px;
+  }
+  
+  .title-input {
+    display: flex; /* 使用 flex 布局 */
+    justify-content: space-between; /* 左右对齐 */
+    align-items: center; /* 垂直居中对齐 */
+    margin-bottom: 10px; /* 标题输入框与文本区域之间的间距 */
+  }
+  
+  .title-input ion-input {
+    border: none; /* 移除默认边框 */
+    border-bottom: 1px solid #ccc; /* 添加下边框 */
+    flex: 1; /* 使输入框填满可用空间 */
+    margin-right: 10px; /* 输入框与字数计数器之间的间距 */
+  }
+  
+  .char-counter {
+    color: gray; /* 字数计数器的颜色 */
+    font-size: 16px; /* 字数计数器的字体大小 */
+    white-space: nowrap; /* 防止换行 */
+  }
+  
+  .footer {
+    display: flex; /* 使用 flex 布局 */
+    justify-content: space-between; /* 左右对齐 */
+    align-items: center; /* 垂直居中对齐 */
+    padding-left: 10px;
+    height: 60px; /* 设置底部的高度 */
+    background-color:#f0f0f0; /* 设置背景色 */
+  }
+  
+  .left-icons {
+    display: flex; /* 使用 flex 布局 */
+    align-items: center; /* 垂直居中对齐 */
+  }
+  
+  .location-tag {
+    display: flex; /* 使用 flex 布局 */
+    justify-content: space-between; /* 左右对齐 */
+    align-items: center; /* 垂直居中对齐 */
+    background-color: white;
+    width: 110px;
+    height: 40px;
+    border-radius: 20px;
+    margin-right: 20px;
+    margin-top: 5px;
+    padding-right: 10px;
+  }
+
+  .footer-button{
+    color:black; 
+    font-size: 40px;
+    margin-right: 20px;
+    margin-top: 30px;
+    margin-bottom: 10px;
+  }

+ 22 - 0
fashion-app/src/app/send-post/send-post.component.spec.ts

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

+ 105 - 0
fashion-app/src/app/send-post/send-post.component.ts

@@ -0,0 +1,105 @@
+import { CommonModule } from '@angular/common';
+import { Component, OnInit } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { Router } from '@angular/router';
+import { NavController } from '@ionic/angular';
+import { IonButton, IonButtons,  IonContent, IonFooter, IonHeader, IonIcon, IonInput, IonItem,  IonTextarea,  IonTitle, IonToolbar,  } from '@ionic/angular/standalone';
+import { addIcons } from 'ionicons';
+import { atOutline, chevronBackSharp, closeOutline, happyOutline, imageOutline } from 'ionicons/icons';
+import { CloudObject, CloudUser } from 'src/lib/ncloud';
+
+addIcons({chevronBackSharp,imageOutline,atOutline,happyOutline,closeOutline });
+@Component({
+  selector: 'app-send-post',
+  templateUrl: './send-post.component.html',
+  styleUrls: ['./send-post.component.scss'],
+  standalone: true,
+   imports: [IonHeader,IonToolbar,IonTitle,IonContent,IonItem,
+      IonButton,IonIcon,IonButtons,IonInput,IonFooter,CommonModule,FormsModule,IonTextarea,],
+})
+export class SendPostComponent  implements OnInit {
+  inputText: string = ''; // 用于绑定输入框的内容
+  title: string = ''; // 帖子标题
+  showLocationTag: boolean = true; // 控制标签是否显示
+  remainingChars: number = 20; // 剩余字符数
+  images: string[] = []; // 存储图片的数组
+  tags: string[] = []; // 存储标签的数组
+  ngOnInit() {}
+
+  constructor(private router: Router,private navCtrl: NavController) {}
+
+  goBack() {
+
+    this.navCtrl.back(); // 返回上一页
+  
+    }
+// 发布帖子
+publishPost() {
+   // 检查发布按钮是否处于激活状态
+   if (this.inputText.length === 0 || this.remainingChars ===20) {
+    console.warn('按钮处于默认样式,无法发布帖子');
+    return; // 如果按钮处于默认样式,直接返回,不执行后续逻辑
+}
+
+  // 创建一个 CloudObject 实例,表示要保存的帖子
+  const post = new CloudObject('post'); // 表名为 'post'
+
+  // 设置帖子内容
+  post.set({
+    user: new CloudUser().toPointer(), // 指向当前用户
+    content: this.inputText, // 帖子内容
+    title: this.title, // 帖子标题
+    image: this.images, // 图片数组
+    tag: this.tags, // 标签数组
+  });
+
+  // 保存帖子到数据库
+  post.save()
+    .then(() => {
+      console.log('帖子已发布');
+      // 清空输入框和其他状态
+      this.inputText = '';
+      this.title = '';
+      this.images = [];
+      this.tags = [];
+    })
+    .catch((error:any) => {
+      console.error('发布帖子时出错:', error);
+    });
+}
+
+//  删除标签
+    removeLocationTag() {
+      this.showLocationTag = false; // 设置为 false 隐藏标签
+    }
+//  更新标题长度
+    updateTitleLength() {
+      this.remainingChars = 20 - this.title.length; // 更新剩余字符数
+    }
+
+
+     // 处理文件选择
+  uploadImage() {
+    const fileInput = document.querySelector('input[type=file]') as HTMLInputElement; // 使用类型断言;
+    if (fileInput) {
+      fileInput.click(); // 点击文件输入框
+    }
+  }
+
+  // 处理文件选择后的事件
+  onFileSelected(event: Event) {
+    const input = event.target as HTMLInputElement;
+    if (input.files && input.files.length > 0) {
+      const file = input.files[0];
+      const reader = new FileReader();
+
+      reader.onload = (e: any) => {
+        // 将图片数据存储到 images 数组中
+        this.images.push(e.target.result); // 将 Base64 编码的图片数据添加到数组
+      };
+
+      reader.readAsDataURL(file); // 读取文件为 Data URL
+    }
+  }
+ 
+}

+ 2 - 0
fashion-app/src/app/tab2/tab2.page.html

@@ -59,6 +59,8 @@
     </ion-card-content>
   </ion-card>
 
+  <ion-button expand="block" (click)="gosendpost()">发帖</ion-button>
+
 </ion-content>
 
 

+ 8 - 1
fashion-app/src/app/tab2/tab2.page.ts

@@ -9,6 +9,7 @@ import { RecommendationService } from 'src/lib/recommend';
 import { CloudUser } from 'src/lib/ncloud';
 import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
 import { ModalController } from '@ionic/angular/standalone';
+import { Router } from '@angular/router';
 
 
 @Component({
@@ -47,7 +48,8 @@ async loadPerferList(){
   images:Array<string> = []
   constructor(
     private cdRef:ChangeDetectorRef,
-    private modalCtrl: ModalController
+    private modalCtrl: ModalController,
+    private router:Router,
   ){
     // 示例任务,自己生成图片后请存储新的ID
     this.imagineWork = new ImagineWork("lpJGiFwWeA");
@@ -95,4 +97,9 @@ async loadPerferList(){
 
   }
 
+
+  gosendpost(){
+    this.router.navigate(['sendpost']);
+  }
+
 }

+ 2 - 0
fashion-app/src/app/tab3/tab3.page.ts

@@ -46,6 +46,8 @@ export class Tab3Page {
     countdownTimer: number = 0; // 计时器初始值
     timerInterval: any; // 用于存储定时器的引用
   images:Array<string> = []
+
+  
     constructor(private alertController: AlertController,private modalCtrl:ModalController,
       private router:Router, private cdRef:ChangeDetectorRef) { }
 

+ 1 - 0
fashion-app/src/app/tabs/tabs.routes.ts

@@ -60,6 +60,7 @@ export const routes: Routes = [
       loadComponent: () =>
         import('../chat-content/chat-content.component').then((m) => m.ChatContentComponent),
     },
+
       
       {
         path: '',