Kaynağa Gözat

新增种花功能

warrior 3 ay önce
ebeveyn
işleme
1816c348b1
35 değiştirilmiş dosya ile 1180 ekleme ve 108 silme
  1. BIN
      projects/live-app/public/img/亲密度.png
  2. BIN
      projects/live-app/public/img/圈子.png
  3. BIN
      projects/live-app/public/img/圈子_active.png
  4. BIN
      projects/live-app/public/img/客服.png
  5. BIN
      projects/live-app/public/img/小助手.png
  6. 5 1
      projects/live-app/src/modules/account/account.modules.routes.ts
  7. 52 19
      projects/live-app/src/modules/account/bankcard/bankcard.component.html
  8. 26 21
      projects/live-app/src/modules/account/bankcard/bankcard.component.scss
  9. 14 35
      projects/live-app/src/modules/account/bankcard/bankcard.component.ts
  10. 7 3
      projects/live-app/src/modules/account/wattle/wattle.component.html
  11. 81 0
      projects/live-app/src/modules/account/withdrawal/withdrawal.component.html
  12. 102 0
      projects/live-app/src/modules/account/withdrawal/withdrawal.component.scss
  13. 24 0
      projects/live-app/src/modules/account/withdrawal/withdrawal.component.spec.ts
  14. 97 0
      projects/live-app/src/modules/account/withdrawal/withdrawal.component.ts
  15. 1 1
      projects/live-app/src/modules/live/call-log/detail/detail.component.html
  16. 1 1
      projects/live-app/src/modules/live/chat/chat.component.html
  17. 18 3
      projects/live-app/src/modules/live/chat/chat.component.ts
  18. 0 1
      projects/live-app/src/modules/tabs/my/my.component.ts
  19. 1 1
      projects/live-app/src/modules/tabs/notice/notice.component.html
  20. 104 0
      projects/live-app/src/modules/tabs/space/space.component.html
  21. 141 0
      projects/live-app/src/modules/tabs/space/space.component.scss
  22. 28 0
      projects/live-app/src/modules/tabs/space/space.component.spec.ts
  23. 186 0
      projects/live-app/src/modules/tabs/space/space.component.ts
  24. 6 0
      projects/live-app/src/modules/tabs/tabs.modules.routes.ts
  25. 2 2
      projects/live-app/src/modules/tabs/tabs/tabs.component.html
  26. 10 4
      projects/live-app/src/modules/tabs/tabs/tabs.component.ts
  27. 0 3
      projects/live-app/src/modules/user/feedback/feedback.component.html
  28. 1 1
      projects/live-app/src/modules/user/feedback/feedback.component.scss
  29. 10 9
      projects/live-app/src/modules/user/feedback/feedback.component.ts
  30. 28 0
      projects/live-app/src/modules/user/release/release.component.html
  31. 75 0
      projects/live-app/src/modules/user/release/release.component.scss
  32. 28 0
      projects/live-app/src/modules/user/release/release.component.spec.ts
  33. 92 0
      projects/live-app/src/modules/user/release/release.component.ts
  34. 5 1
      projects/live-app/src/modules/user/user.modules.routes.ts
  35. 35 2
      projects/live-app/src/services/aichart.service.ts

BIN
projects/live-app/public/img/亲密度.png


BIN
projects/live-app/public/img/圈子.png


BIN
projects/live-app/public/img/圈子_active.png


BIN
projects/live-app/public/img/客服.png


BIN
projects/live-app/public/img/小助手.png


+ 5 - 1
projects/live-app/src/modules/account/account.modules.routes.ts

@@ -7,6 +7,7 @@ import { DetailComponent } from './order/detail/detail.component';
 import { OrderComponent } from './order/order.component';
 import { RechargeComponent } from './recharge/recharge.component';
 import { WattleComponent } from './wattle/wattle.component';
+import { WithdrawalComponent } from './withdrawal/withdrawal.component';
 const routes: Routes = [
   {
     path: '',
@@ -41,7 +42,10 @@ const routes: Routes = [
     path: 'noticelog',
     component: NoticeLogComponent,
   },
-  
+  {
+    path: 'withdrawal',
+    component: WithdrawalComponent,
+  },
 ]
 @NgModule({
   imports: [RouterModule.forChild(routes)],

+ 52 - 19
projects/live-app/src/modules/account/bankcard/bankcard.component.html

@@ -24,28 +24,61 @@
     } }
   </div>
   <ion-button class="add_btn" (click)="addCard()">添加银行卡</ion-button>
+</div>
+<ion-modal
+  trigger="open-modal"
+  [isOpen]="isModalOpen"
+  (didDismiss)="isModalOpen = false"
+>
+  <ng-template>
+    <ion-toolbar>
+      <ion-buttons slot="start">
+        <ion-button (click)="changeCityCancel('cancel')">取消</ion-button>
+      </ion-buttons>
+      <ion-buttons slot="end">
+        <ion-button (click)="changeCityCancel('confirm')">确定</ion-button>
+      </ion-buttons>
+    </ion-toolbar>
+    <div class="model">
+      <input
+        type="text"
+        [(ngModel)]="bankinfo.bankcard"
+        autocomplete="off"
+        placeholder="请填写银行卡号"
+        autocomplete="new-password"
+      />
 
-  <!-- <Modal [(ngModel)]="isModalOpen" [transparent]="true" [title]="'银行卡信息'" [footer]="footer">
-		<div class="model">
-
-			<input type="text" [(ngModel)]='bankinfo.bankcard' autocomplete="off" placeholder="请填写银行卡号"
-				autocomplete="new-password">
-
-			<div class="line"></div>
-
-			<input type="text" [(ngModel)]='bankinfo.idcard' maxlength="18" autocomplete="off" placeholder="请填写身份证号"
-				autocomplete="new-password">
+      <div class="line"></div>
 
-			<div class="line"></div>
+      <input
+        type="text"
+        [(ngModel)]="bankinfo.idcard"
+        maxlength="18"
+        autocomplete="off"
+        placeholder="请填写身份证号"
+        autocomplete="new-password"
+      />
 
-			<input type="text" [(ngModel)]='bankinfo.name' maxlength="18" autocomplete="off" placeholder="请填写真实姓名"
-				autocomplete="new-password">
+      <div class="line"></div>
 
-			<div class="line"></div>
+      <input
+        type="text"
+        [(ngModel)]="bankinfo.name"
+        maxlength="18"
+        autocomplete="off"
+        placeholder="请填写真实姓名"
+        autocomplete="new-password"
+      />
 
-			<input type="text" [(ngModel)]='bankinfo.mobile' maxlength="18" autocomplete="off" placeholder="请填写银行预留手机号"
-				autocomplete="new-password">
+      <div class="line"></div>
 
-		</div>
-	</Modal> -->
-</div>
+      <input
+        type="text"
+        [(ngModel)]="bankinfo.mobile"
+        maxlength="18"
+        autocomplete="off"
+        placeholder="请填写银行预留手机号"
+        autocomplete="new-password"
+      /></div
+  ></ng-template>
+</ion-modal>

+ 26 - 21
projects/live-app/src/modules/account/bankcard/bankcard.component.scss

@@ -85,32 +85,37 @@
 		bottom: 1vh;
 		width: 80%;
 		left: 10vw;
-		background: #92a1ff;
+		--background: #92a1ff;
 		border-radius: 18px;
 	}
 
-	.model {
-		height: 30vh;
+
+}
+.model {
+	height: 300px;
+	width: 100%;
+	// border: 1px solid #000000;
+	padding: 10px;
+	input {
 		width: 100%;
-		border: 1px solid #000000;
-
-		input {
-			width: 100%;
-			height: 6vh;
-			height: 1;
-			border-radius: 6px;
-			border: none;
-			padding: 0 10px;
-			font-size: 14px;
-			flex: 1;
+		height: 6vh;
+		height: 1;
+		border-radius: 6px;
+		border: none;
+		padding: 0 10px;
+		font-size: 14px;
+		flex: 1;
 
-		}
+	}
 
-		.line {
-			margin: 4px 0;
-			width: 100%;
-			height: 1px;
-			background-color: #a2a2a2;
-		}
+	.line {
+		margin: 4px 0;
+		width: 100%;
+		height: 1px;
+		background-color: #a2a2a2;
 	}
+}
+ion-modal {
+  --height: auto;
+  align-items: end;
 }

+ 14 - 35
projects/live-app/src/modules/account/bankcard/bankcard.component.ts

@@ -5,17 +5,19 @@ import * as Parse from 'parse';
 import { HttpClient } from '@angular/common/http';
 import { ToastController } from '@ionic/angular';
 import { ionicStandaloneModules } from '../../ionic-standalone.modules';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
 @Component({
   selector: 'app-bankcard',
   templateUrl: './bankcard.component.html',
   styleUrls: ['./bankcard.component.scss'],
 	standalone: true,
-  imports: [...ionicStandaloneModules,NavComponent],
+  imports: [...ionicStandaloneModules,NavComponent,CommonModule, FormsModule],
 })
 export class BankcardComponent implements OnInit {
   constructor(
     private http: HttpClient,
-    public toastController: ToastController
+    private toastController: ToastController
   ) {}
   company: string = localStorage.getItem('company') || '';
   account: any = null;
@@ -27,9 +29,6 @@ export class BankcardComponent implements OnInit {
   };
   adding: boolean = false;
   isModalOpen: boolean = false;
-  setOpen(isOpen: boolean) {
-    this.isModalOpen = isOpen;
-  }
   async ngOnInit() {
     await this.getAccountInfo();
   }
@@ -45,31 +44,6 @@ export class BankcardComponent implements OnInit {
     }
   }
 
-  footer = [
-    {
-      text: '取消',
-      onPress: () => {
-        console.log('ok');
-        this.onClose();
-      },
-    },
-    {
-      text: '确定',
-      onPress: () => {
-        console.log('ok');
-        if (this.adding) {
-          return;
-        }
-        this.adding = true;
-        this.confirm();
-      },
-    },
-  ];
-
-  onClose() {
-    this.isModalOpen = false;
-  }
-
   async confirm() {
     let cardInfo = this.bankinfo;
     for (const key in cardInfo) {
@@ -77,7 +51,7 @@ export class BankcardComponent implements OnInit {
         const toast = await this.toastController.create({
           message: '请将信息填写完整',
           color: 'warning',
-          duration: 100000,
+          duration: 1500,
         });
         toast.present();
         this.adding = false;
@@ -103,7 +77,7 @@ export class BankcardComponent implements OnInit {
           const toast = await this.toastController.create({
             message: '卡状态异常,请更换卡',
             color: 'warning',
-            duration: 100000,
+            duration: 1500,
           });
           toast.present();
           this.adding = false;
@@ -113,7 +87,7 @@ export class BankcardComponent implements OnInit {
         const toast = await this.toastController.create({
           message: res.data.msg,
           color: 'warning',
-          duration: 100000,
+          duration: 1500,
         });
         toast.present();
         this.adding = false;
@@ -122,7 +96,7 @@ export class BankcardComponent implements OnInit {
         const toast = await this.toastController.create({
           message: '服务错误请稍后重试',
           color: 'warning',
-          duration: 100000,
+          duration: 1500,
         });
         toast.present();
         this.adding = false;
@@ -155,7 +129,12 @@ export class BankcardComponent implements OnInit {
       await account.save();
     }
   }
-
+  changeCityCancel(type: string) {
+    if (type === 'confirm') {
+      this.confirm()
+    }
+    this.isModalOpen = false;
+  }
   addCard() {
     this.isModalOpen = true;
   }

+ 7 - 3
projects/live-app/src/modules/account/wattle/wattle.component.html

@@ -7,14 +7,18 @@
           <div class="count">{{ account?.balance?.toFixed(2) || 0 }}</div>
           <div class="title">钻石余额</div>
         </div>
+        <div class="balance">
+          <div class="count">{{ account?.balance?.toFixed(2) || 0 }}</div>
+          <div class="title">可提现</div>
+        </div>
       </div>
       <div class="figure">
         <div class="recharge" (click)="recharge()">充值</div>
-        <!-- <div class="recharges" (click)="withdrawal()">提现</div> -->
+        <div class="recharges" (click)="withdrawal()">提现</div>
       </div>
     </div>
 
-    <!-- <div class="install" (click)="toBank()">
+    <div class="install" (click)="toBank()">
       <div class="install-to">
         <div class="name">我的银行卡</div>
       </div>
@@ -22,7 +26,7 @@
         class="img"
         src="https://file-cloud.fmode.cn/uiZD6NisQm/20220808/9sq3d1093746.png"
       />
-    </div> -->
+    </div>
     <div class="install" (click)="record()">
       <div class="install-to">
         <div class="name">动账记录</div>

+ 81 - 0
projects/live-app/src/modules/account/withdrawal/withdrawal.component.html

@@ -0,0 +1,81 @@
+<nav title="申请提现"></nav>
+<div class="top">
+  <div class="way">
+    <div class="icon"></div>
+    提现方式
+  </div>
+  <div class="choose">
+    <div class="type">
+      <div style="display: flex">
+        <div class="icon"></div>
+        银行卡
+      </div>
+      <div class="bank">
+        <div class="name">所属银行:</div>
+        <input
+          type="text"
+          [(ngModel)]="bankinfo.bankName"
+          maxlength="8"
+          name="bankName"
+          autocomplete="off"
+          placeholder="请输入所属银行"
+          class="input"
+        />
+      </div>
+      <div class="bank">
+        <div class="name">姓名:</div>
+        <input
+          type="text"
+          [(ngModel)]="bankinfo.name"
+          maxlength="8"
+          name="names"
+          autocomplete="off"
+          placeholder="请输入姓名"
+          class="input"
+        />
+      </div>
+      <div class="bank">
+        <div class="name">联系电话:</div>
+        <input
+          type="number"
+          [(ngModel)]="bankinfo.mobile"
+          maxlength="8"
+          name="mobile"
+          autocomplete="off"
+          placeholder="请输入联系电话"
+          class="input"
+        />
+      </div>
+      <div class="bank">
+        <div class="name">卡号:</div>
+        <input
+          type="number"
+          [(ngModel)]="bankinfo.bankcard"
+          maxlength="8"
+          name="accountId"
+          autocomplete="off"
+          placeholder="请输入卡号"
+          class="input"
+        />
+      </div>
+    </div>
+  </div>
+  <div class="way">
+    <div class="icon"></div>
+    提现金额
+  </div>
+  <div class="chooses">
+    <div>¥</div>
+    <input
+      type="number"
+      [(ngModel)]="price"
+      maxlength="8"
+      name="price"
+      autocomplete="off"
+      placeholder="请输入提现金额"
+      class="input"
+    />
+  </div>
+  <div class="withdrawal" (click)="withdrawal()">立即提现</div>
+  <div class="tips">温馨提示:提现需收取10%手续费</div>
+</div>

+ 102 - 0
projects/live-app/src/modules/account/withdrawal/withdrawal.component.scss

@@ -0,0 +1,102 @@
+.nav {
+  width: 100%;
+  height: 6vh;
+  line-height: 6vh;
+  color: #000000;
+  background: #dbe5fd;
+  z-index: 100;
+}
+
+.top {
+  background-image: url("https://file-cloud.fmode.cn/Qje9D4bqol/20241220/b313ov054708770.png");
+  background-repeat: no-repeat;
+  background-position: center top;
+  background-size: 100% 100%;
+  height: 100%;
+  padding-bottom: 40px;
+  width: 100%;
+
+  .way {
+    margin: 20px;
+    display: flex;
+    color: #5973ff;
+
+    .icon {
+      background: #5973ff;
+      width: 3px;
+      height: 20px;
+      margin-right: 5px;
+    }
+  }
+
+  .choose {
+    margin: 20px;
+    border-radius: 9px;
+    border: 1px solid #000000;
+    padding: 10px;
+
+    .type {
+      // display: flex;
+
+      .icon {
+        background: #5973ff;
+        margin: auto 0;
+        width: 15px;
+        height: 15px;
+        // border: 1PX solid #000000;
+        border-radius: 50%;
+        margin-right: 5px;
+      }
+
+      .input {
+        background: none;
+        // border: none;
+        border: 1px solid #cbcbcb;
+        border-radius: 4px;
+        padding: 2px 4px;
+      }
+
+      .bank {
+        margin: 10px;
+      }
+    }
+  }
+
+  .chooses {
+    margin: 20px;
+    border-radius: 9px;
+    border: 1px solid #000000;
+    padding: 10px;
+    display: flex;
+
+    .input {
+      background: none;
+      border: none;
+    }
+  }
+
+  .withdrawal {
+    width: 60%;
+    margin: 50px auto;
+    text-align: center;
+    background: #5973ff;
+    border-radius: 18px;
+    color: #ffffff;
+    padding: 10px 0;
+  }
+
+  .withdrawals {
+    width: 60%;
+    margin: 50px auto;
+    text-align: center;
+    background: #676666;
+    border-radius: 18px;
+    color: #ffffff;
+    padding: 10px 0;
+  }
+  .tips{
+    text-align: center;
+    font-size: 12px;
+    color: #8f8f8f;
+  }
+}

+ 24 - 0
projects/live-app/src/modules/account/withdrawal/withdrawal.component.spec.ts

@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { IonicModule } from '@ionic/angular';
+
+import { WithdrawalComponent } from './withdrawal.component';
+
+describe('WithdrawalComponent', () => {
+  let component: WithdrawalComponent;
+  let fixture: ComponentFixture<WithdrawalComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ WithdrawalComponent ],
+      imports: [IonicModule.forRoot()]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(WithdrawalComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 97 - 0
projects/live-app/src/modules/account/withdrawal/withdrawal.component.ts

@@ -0,0 +1,97 @@
+import { CommonModule } from '@angular/common';
+import { Component, OnInit } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import * as Parse from 'parse';
+import { NavComponent } from '../../../app/components/nav/nav.component';
+import { AiChatService } from '../../../services/aichart.service';
+import {
+  ionicStandaloneModules,
+  ToastController,
+} from '../../ionic-standalone.modules';
+@Component({
+  selector: 'app-withdrawal',
+  templateUrl: './withdrawal.component.html',
+  styleUrls: ['./withdrawal.component.scss'],
+  standalone: true,
+  imports: [...ionicStandaloneModules, NavComponent, CommonModule, FormsModule],
+})
+export class WithdrawalComponent implements OnInit {
+  constructor(private toastController: ToastController,
+    private aiServ: AiChatService,
+    ) {}
+  price: number = 0;
+  balance:number = 0;
+  bankinfo: any = {
+    bankcard: '',
+    name: '',
+    idcard: '',
+    mobile: '',
+  };
+  data: any = [
+    { value: 0, name: '银行卡' },
+    { value: 1, name: '微信' },
+  ];
+  value: Number = 0;
+  account?: Parse.Object
+  ngOnInit() {
+    this.getAccount();
+  }
+  async getAccount() {
+    let id = Parse.User.current()?.id;
+    let query = new Parse.Query('Account');
+    query.equalTo('user', id);
+    query.equalTo('company', this.aiServ.company);
+    this.account = await query.first();
+    if(this.account?.get('bank')){
+      this.bankinfo = this.account?.get('bank')[0];
+    }
+    console.log(this.account);
+  }
+  async withdrawal() {
+    if (!this.bankinfo.name || !this.bankinfo.bankcard || !this.bankinfo.mobile) {
+      this.toast('请先绑定银行卡', 1500);
+      return;
+    }
+    if (!this.price || this.price < 0) {
+      this.toast('请输入正确金额', 1500);
+      return;
+    }
+    if (this.balance < this.price) {
+      this.toast('提现金额不得超过余额!', 1500);
+      return;
+    }
+    if (this.price < 100) {
+      this.toast('最低提现金额为100', 1500);
+      return;
+    }
+    let UserAgentWithdraw = Parse.Object.extend('UserAgentWithdraw');
+    let userAgentWithdraw = new UserAgentWithdraw();
+    userAgentWithdraw.set('count', Number(this.data.price));
+    userAgentWithdraw.set('type', 'bank');
+    userAgentWithdraw.set('name', this.bankinfo.name);
+    userAgentWithdraw.set('count', this.price);
+    userAgentWithdraw.set('company', {
+      __type: 'Pointer',
+      className: 'Company',
+      objectId: this.aiServ.company,
+    });
+    userAgentWithdraw.set('user', {
+      __type: 'Pointer',
+      className: '_User',
+      objectId: Parse.User.current()?.id,
+    });
+    userAgentWithdraw.set('bank', this.bankinfo);
+    await userAgentWithdraw.save();
+    this.toast('申请成功', 1500);
+    history.back();
+  }
+
+  async toast(title: string, time: number, color?: string) {
+    const toast = await this.toastController.create({
+      message: title,
+      color: color ?? 'warning',
+      duration: time || 1500,
+    });
+    toast.present();
+  }
+}

+ 1 - 1
projects/live-app/src/modules/live/call-log/detail/detail.component.html

@@ -1,4 +1,4 @@
-<nav title="订单详情"></nav>
+<nav title="通话详情"></nav>
 <ion-content class="content">
   <div class="status-view">
     <img

+ 1 - 1
projects/live-app/src/modules/live/chat/chat.component.html

@@ -37,7 +37,7 @@
         @if (uid) {
         <ion-item (click)="onRjects()" class="clear" [button]="true" [detail]="false">
           <ion-icon name="person-remove-outline"></ion-icon
-          >{{ this.isRet?.id ? "移除黑名单" : "加入黑名单" }}</ion-item
+          >{{ this.isRet?.get('isAward') ? "移除黑名单" : "加入黑名单" }}</ion-item
         >
         <ion-item class="clear" [button]="true" [detail]="false"
           ><ion-icon name="star-outline"></ion-icon>添加关注</ion-item

+ 18 - 3
projects/live-app/src/modules/live/chat/chat.component.ts

@@ -286,10 +286,25 @@ export class ChatComponent implements OnInit {
             if (!this.isRet?.id) {
               let obj = Parse.Object.extend('EventLog');
               this.isRet = new obj();
-              this.isRet?.set('isAward', !this.isRet?.get('isAward'));
-              await this.isRet?.save();
             }
-            this.msgServe.delMsg(this.channel);
+            this.isRet?.set('isAward', !this.isRet?.get('isAward'));
+            this.isRet?.set('company', {
+              __type: 'Pointer',
+              className: 'Company',
+              objectId: this.aiServ.company,
+            });
+            this.isRet?.set('invited', {
+              __type: 'Pointer',
+              className: '_User',
+              objectId: this.uid,
+            });
+            this.isRet?.set('user', {
+              __type: 'Pointer',
+              className: '_User',
+              objectId: Parse.User.current()?.id!,
+            });
+            await this.isRet?.save();
+            // this.msgServe.delMsg(this.channel);
           },
         },
       ],

+ 0 - 1
projects/live-app/src/modules/tabs/my/my.component.ts

@@ -1,6 +1,5 @@
 import { Component, OnInit } from '@angular/core';
 import { LoadingController, ToastController } from '@ionic/angular';
-
 import * as Parse from 'parse';
 import { AgreementComponent } from '../../login/agreement/agreement.component';
 import { AlertController, ModalController } from '@ionic/angular';

+ 1 - 1
projects/live-app/src/modules/tabs/notice/notice.component.html

@@ -96,7 +96,7 @@
           </ion-item>
           <ion-item class="li" (click)="isOpen = true">
             <img
-              src="img/小助手.png"
+              src="img/客服.png"
               class="avatar"
               slot="start"
               alt="avatar"

+ 104 - 0
projects/live-app/src/modules/tabs/space/space.component.html

@@ -0,0 +1,104 @@
+<ion-header [translucent]="true" class="header">
+  <div class="top">
+    <!-- <div class="more"></div> -->
+    <ion-segment
+      [scrollable]="true"
+      (ionChange)="segmentChanged($event)"
+      layout="icon-bottom"
+      value="all"
+      mode="md"
+    >
+      <ion-segment-button value="all" class="tabs" content-id="all">
+        <ion-label>全部</ion-label>
+      </ion-segment-button>
+      <ion-segment-button value="self" class="tabs" content-id="self">
+        <ion-label>我发布的</ion-label>
+      </ion-segment-button>
+    </ion-segment>
+    <div class="more">
+      <ion-button id="post-trigger"
+        ><ion-icon name="add-outline"></ion-icon
+      ></ion-button>
+    </div>
+  </div>
+</ion-header>
+<ion-content class="content">
+  <ion-popover
+    trigger="post-trigger"
+    [dismissOnSelect]="true"
+    triggerAction="click"
+  >
+    <ng-template>
+      <ion-list>
+        <ion-item
+          class="post"
+          (click)="toUrl('user/release')"
+          [button]="true"
+          [detail]="false"
+          ><ion-icon name="share-outline"></ion-icon>发布帖子</ion-item
+        >
+      </ion-list>
+    </ng-template>
+  </ion-popover>
+  <div class="tab-content">
+    @for (item of list; track $index) {
+    <div class="card">
+      <div class="user-data">
+        <div
+          (click)="toUrl('user/profile/' + item.uid)"
+          class="pendant"
+          [style.background-image]="
+            'url(https://file-cloud.fmode.cn/Qje9D4bqol/20241109/vv1tvb032259054.png)'
+          "
+        >
+          <img [src]="item.avatar" class="avatar" alt="" />
+        </div>
+        <div class="user-dateil">
+          <div class="dateil">
+            <div class="user-name">{{ item.nickname }}</div>
+            @if (item.isVip) {
+            <img src="img/VIP.png" alt="" />
+            } @if (item.identyType == 'anchor') {
+            <div class="tag">主播</div>
+            }
+          </div>
+          <div class="time">{{ item.formatted_date }}</div>
+        </div>
+      </div>
+      <div class="post-dateil">
+        <div class="text-content">{{ item.content }}</div>
+        <div class="imgs">
+          @for (img of item.images; track $index) {
+          <img [src]="img" alt="" (click)="onShowImg(img)" />
+          }
+        </div>
+      </div>
+      <div class="tool">
+        <div
+          [ngClass]="{
+            'action-icon': item.isPostLog,
+            'tool-item': true
+          }"
+          (click)="onPostLog(item, $index)"
+        >
+          <ion-icon name="heart-circle"></ion-icon>
+          {{ item.postCount }}
+        </div>
+        @if (item.uid == user.id) {
+          <div class="tool-item" style="color: #1a65eb;" (click)="delPost(item.objectId,$index)">
+            <ion-icon name="remove-circle"></ion-icon>
+          </div>
+        }@else {
+          <div class="tool-item" (click)="onReport()">
+            <ion-icon name="warning"></ion-icon>
+          </div>
+        }
+      </div>
+    </div>
+    }
+    <ion-infinite-scroll (ionInfinite)="onIonInfinite($event)">
+      <ion-infinite-scroll-content></ion-infinite-scroll-content>
+    </ion-infinite-scroll>
+  </div>
+</ion-content>
+<app-image-preview [image]="currenImg" #preview></app-image-preview>

+ 141 - 0
projects/live-app/src/modules/tabs/space/space.component.scss

@@ -0,0 +1,141 @@
+.header {
+  padding: 10px;
+  border-bottom: 1px solid #dfdfdf;
+  background: white;
+  .top {
+    display: flex;
+    justify-content: space-between;
+    ion-segment {
+      justify-content: start;
+      padding: 0 3.2vw;
+      position: sticky;
+      top: 0;
+      // background: #fd6f6a;
+    }
+    // ion-segment-button {
+    //   color: #fd6f6a;
+    //   --indicator-color: #fd6f6a;
+    // }
+    .more {
+      width: 50px;
+      margin: 0 10px;
+      display: flex;
+      align-items: center;
+      justify-content: space-around;
+      img {
+        width: 20px;
+        height: 20px;
+      }
+      ion-button {
+        --background: white;
+        --background-hover: white;
+        --background-activated: white;
+        --background-focused: white;
+        --color: #000;
+      }
+    }
+  }
+}
+.content {
+  --padding-bottom: 100px;
+  --background: #f8f8f8;
+  .tab-content {
+    .card {
+      background-color: white;
+      margin-bottom: 10px;
+      padding: 10px;
+      .user-data {
+        display: flex;
+        align-items: center;
+        padding-bottom: 4px;
+        border-bottom: 1px solid #dfdfdf;
+        .pendant {
+          width: 40px;
+          height: 40px;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          background-size: 100% 100%;
+          .avatar {
+            width: 30px;
+            height: 30px;
+            border-radius: 50%;
+          }
+        }
+        .user-dateil {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          flex: 1;
+          .dateil {
+            display: flex;
+            align-items: center;
+            .user-name {
+              margin-left: 10px;
+            }
+            .tag {
+              border: 1px solid;
+              padding: 0 4px;
+              margin-left: 10px;
+              border-radius: 4px;
+              font-size: 12px;
+              color: #a3a3a3;
+            }
+            img{
+              width: 30px;
+              margin-left: 6px;
+            }
+          }
+          .time {
+            font-size: 12px;
+            color: #c5c5c5;
+          }
+        }
+      }
+      .post-dateil {
+        margin: 10px 0 10px 50px;
+        .text-content {
+          font-size: 14px;
+        }
+        .imgs {
+          display: grid;
+          grid-template-columns: repeat(4, 70px);
+          justify-content: space-between;
+          flex-wrap: wrap;
+          img {
+            height: 70px;
+            width: 70px;
+            object-fit: cover;
+            margin-top: 10px;
+          }
+        }
+      }
+      .tool {
+        margin-left: 50px;
+        margin-top: 20px;
+        display: flex;
+        justify-content: space-between;
+        .tool-item {
+          display: flex;
+          align-items: center;
+          color: #a3a3a3;
+          // margin-right: 30px;
+          ion-icon {
+            font-size: 30px;
+          }
+        }
+        .action-icon {
+          color: #f36f6f;
+        }
+      }
+    }
+  }
+  .post {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+}
+ion-popover {
+  --width: 130px;
+}

+ 28 - 0
projects/live-app/src/modules/tabs/space/space.component.spec.ts

@@ -0,0 +1,28 @@
+/* tslint:disable:no-unused-variable */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { SpaceComponent } from './space.component';
+
+describe('SpaceComponent', () => {
+  let component: SpaceComponent;
+  let fixture: ComponentFixture<SpaceComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ SpaceComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SpaceComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 186 - 0
projects/live-app/src/modules/tabs/space/space.component.ts

@@ -0,0 +1,186 @@
+import { CommonModule, DatePipe } from '@angular/common';
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { AiChatService } from '../../../services/aichart.service';
+// import { NavComponent } from '../../../app/components/nav/nav.component';
+import {
+  AlertController,
+  ionicStandaloneModules,
+  ToastController,
+} from '../../ionic-standalone.modules';
+import { ImagePreviewComponent } from '../../../app/components/image-preview/image-preview.component';
+import * as Parse from 'parse';
+import { InfiniteScrollCustomEvent } from '@ionic/core';
+
+@Component({
+  selector: 'app-space',
+  templateUrl: './space.component.html',
+  styleUrls: ['./space.component.scss'],
+  standalone: true,
+  imports: [...ionicStandaloneModules, CommonModule, ImagePreviewComponent],
+  providers: [DatePipe],
+})
+export class SpaceComponent implements OnInit {
+  active: string = 'all';
+  list: Array<any> = [];
+  currenImg: string = '';
+  @ViewChild('preview') preview!: ImagePreviewComponent;
+  user:Parse.Object = Parse.User.current()!;
+  constructor(
+    private activateRoute: ActivatedRoute,
+    private router: Router,
+    private aiServ: AiChatService,
+    private alertController: AlertController,
+    private toastController: ToastController
+  ) {}
+
+  ngOnInit() {
+    this.activateRoute.paramMap.subscribe(async (params) => {
+      this.getList();
+    });
+  }
+  async getList() {
+    let arr = await this.aiServ.getPost(
+      10,
+      this.list.length,
+      this.active == 'self' ? Parse.User.current()?.id : undefined
+    );
+    console.log(arr);
+    this.list.push(...arr);
+    if(arr.length == 0){
+      const toast = await this.toastController.create({
+        message: '已加载全部',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+    }
+    return arr;
+  }
+  segmentChanged(e: any) {
+    let { value } = e.detail;
+    this.active = value;
+    this.list = [];
+    this.getList();
+  }
+  onShowImg(url: string) {
+    this.currenImg = url;
+    this.preview.show = 'inline-flex';
+  }
+  async onPostLog(item: any, index: number) {
+    console.log(item);
+    let query = new Parse.Query('DramaPostLog');
+    query.equalTo('dramaPost', item.objectId);
+    query.equalTo('user', Parse.User.current());
+    query.notEqualTo('isDeleted', true);
+    let r = await query.first();
+    if (!r?.id) {
+      let obj = Parse.Object.extend('DramaPostLog');
+      r = new obj();
+      r?.set('company', {
+        __type: 'Pointer',
+        className: 'Company',
+        objectId: this.aiServ.company,
+      });
+      r?.set('dramaPost', {
+        __type: 'Pointer',
+        className: 'DramaPost',
+        objectId: item.objectId,
+      });
+      r?.set('user', Parse.User.current()?.toPointer());
+    }
+    r?.set('isVerify', true);
+    r?.set('type', 'like');
+    await r?.save();
+    const toast = await this.toastController.create({
+      message: `${item.isPostLog ? '已取消点赞' : '已点赞'}`,
+      color: 'success',
+      duration: 1000,
+    });
+    toast.present();
+    this.list[index].postCount = this.list[index].isPostLog
+      ? --this.list[index].postCount
+      : ++this.list[index].postCount;
+    this.list[index].isPostLog = !this.list[index].isPostLog;
+  }
+  async onIonInfinite(ev: any) {
+    let result = await this.getList();
+    if (this.active == 'all' && result.length == 0) {
+      (ev as InfiniteScrollCustomEvent).target.disabled = true;
+    }
+    setTimeout(() => {
+      (ev as InfiniteScrollCustomEvent).target.complete();
+    }, 500);
+  }
+  toUrl(url: string) {
+    this.router.navigate([url]);
+  }
+  async delPost(id:string,index:number){
+    const alert = await this.alertController.create({
+      cssClass: 'my-custom-class',
+      header: '提示',
+      message: '确定删除该种花吗?',
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel',
+          handler: (data) => {},
+        },
+        {
+          text: '确定',
+          cssClass: 'secondary',
+          handler:async (data) => {
+            let query = new Parse.Query('DramaPost');
+            let post = await query.get(id);
+            post.set('isDeleted',true)
+            await post.save();
+            const toast = await this.toastController.create({
+              message: '删除成功',
+              color: 'success',
+              duration: 1000,
+            });
+            toast.present();
+            this.list.splice(index,1)
+          },
+        },
+      ],
+    });
+    await alert.present();
+  }
+  async onReport() {
+    const alert = await this.alertController.create({
+      cssClass: 'my-custom-class',
+      header: '举报',
+      message: '请填写你需要举报的内容',
+      inputs: [
+        {
+          name: 'report',
+          type: 'textarea',
+          placeholder: '举报内容',
+        },
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel',
+          handler: (data) => {},
+        },
+        {
+          text: '确定',
+          cssClass: 'secondary',
+          handler:async (data) => {
+            let report = data.report;
+            console.log(report);
+            const toast = await this.toastController.create({
+              message: '感谢您的反馈',
+              color: 'success',
+              duration: 1000,
+            });
+            toast.present();
+          },
+        },
+      ],
+    });
+    await alert.present();
+  }
+}

+ 6 - 0
projects/live-app/src/modules/tabs/tabs.modules.routes.ts

@@ -5,6 +5,7 @@ import { LiveReviewComponent } from './live-review/live-review.component';
 import { MyComponent } from './my/my.component';
 import { NoticeComponent } from './notice/notice.component';
 import { RankingComponent } from './ranking/ranking.component';
+import { SpaceComponent } from './space/space.component';
 const routes: Routes = [
   {
     path: '',
@@ -31,6 +32,11 @@ const routes: Routes = [
     path: 'my', //我的
     component: MyComponent,
   },
+  {
+    path: 'space', //朋友圈
+    component: SpaceComponent,
+  },
+  
 ]
 @NgModule({
   imports: [RouterModule.forChild(routes)],

+ 2 - 2
projects/live-app/src/modules/tabs/tabs/tabs.component.html

@@ -1,11 +1,11 @@
 <div class="tabs">
   @for (item of option; track $index) {
   <div
-    class="buttom {{ $index == 2 ? 'center' : '' }}"
+    class="buttom {{ $index == 99 ? 'center' : '' }}"
     (click)="goTabPage($index, item.url)"
   >
     <img
-      class="icon-img {{ $index == 2 ? 'box-icon' : '' }}"
+      class="icon-img {{ $index == 99 ? 'box-icon' : '' }}"
       src="{{ $index == active ? item.active : item.src }}"
       alt=""
     />

+ 10 - 4
projects/live-app/src/modules/tabs/tabs/tabs.component.ts

@@ -47,11 +47,17 @@ export class TabsComponent implements OnInit {
       url: 'tabs/notice',
       name: '消息',
     },
+    // {
+    //   src: 'img/live.png',
+    //   active: 'img/live.png',
+    //   url: 'tabs/live-review',
+    //   name: '直播',
+    // },
     {
-      src: 'img/live.png',
-      active: 'img/live.png',
-      url: 'tabs/live-review',
-      name: '直播',
+      src: 'img/圈子.png',
+      active: 'img/圈子_active.png',
+      url: 'tabs/space',
+      name: '种花',
     },
     {
       src: 'img/排名.png',

+ 0 - 3
projects/live-app/src/modules/user/feedback/feedback.component.html

@@ -21,11 +21,8 @@
         #upload
         [boxWidth]="380"
         [maxlenght]="8"
-        [files]="fileList"
       ></app-upload>
     </div>
-    <!-- 提交 -->
-    <!-- <ion-button  (click)="submit()" expand="block">提交</ion-button> -->
   </div>
 </ion-content>
 <ion-button class="add_btn" (click)="upload.onUpload()">保存</ion-button>

+ 1 - 1
projects/live-app/src/modules/user/feedback/feedback.component.scss

@@ -59,6 +59,6 @@
   bottom: 1vh;
   width: 80%;
   left: 10vw;
-  background: #92a1ff;
+  --background: #92a1ff;
   border-radius: 18px;
 }

+ 10 - 9
projects/live-app/src/modules/user/feedback/feedback.component.ts

@@ -40,7 +40,8 @@ export class FeedbackComponent implements OnInit {
   }
   onFilesChange(event: any) {
     console.log(event);
-    this.fileList = event;
+    this.fileList = event?.map((item: any) => item.url);
+    this.submit()
   }
   async submit() {
     let user = Parse.User.current();
@@ -56,13 +57,13 @@ export class FeedbackComponent implements OnInit {
       await this.presentToast('请填写内容', 1500, 'danger');
       return;
     }
-    let images = [];
-    for (let i = 0; i < this.fileList.length; i++) {
-      let item = this.fileList[i];
-      images.push({
-        url: item,
-      });
-    }
+    // let images = [];
+    // for (let i = 0; i < this.fileList.length; i++) {
+    //   let item = this.fileList[i];
+    //   images.push({
+    //     url: item,
+    //   });
+    // }
     let mobile = user.get('mobile');
     let Profile = new Parse.Query('Profile');
     Profile.equalTo('user', user.id);
@@ -90,7 +91,7 @@ export class FeedbackComponent implements OnInit {
     }
 
     feedback.set('content', this.content ? this.content : undefined);
-    feedback.set('images', images);
+    feedback.set('images', this.fileList);
     feedback.set('mobile', mobile);
     let result = await feedback.save();
     if (result && result.id) {

+ 28 - 0
projects/live-app/src/modules/user/release/release.component.html

@@ -0,0 +1,28 @@
+<nav title="分享种花"></nav>
+<ion-content class="content">
+  <div class="feedback">
+    <div class="section">
+      <ion-textarea
+        autofocus
+        autoGrow
+        rows="6"
+        cols="20"
+        placeholder="填写你要分享的内容"
+        maxlength="500"
+        (ionChange)="textChange($event)"
+      ></ion-textarea>
+      <span>{{ inputNum }}/500</span>
+    </div>
+    <div class="title">图片</div>
+    <div class="upload">
+      <app-upload
+        (onChange)="onFilesChange($event)"
+        #upload
+        [boxWidth]="380"
+        [maxlenght]="8"
+      ></app-upload>
+    </div>
+  </div>
+  <button class="submit" (click)="upload.onUpload()">发布</button>
+</ion-content>
+<!-- <ion-button class="add_btn" (click)="upload.onUpload()">发布</ion-button> -->

+ 75 - 0
projects/live-app/src/modules/user/release/release.component.scss

@@ -0,0 +1,75 @@
+.content {
+  padding-bottom: 50px;
+  background-image: url("https://file-cloud.fmode.cn/Qje9D4bqol/20241220/b313ov054708770.png") !important;
+  background-repeat: no-repeat;
+  background-position: center top;
+  background-size: 100% 100%;
+  --background: #ffffff00;
+  .submit {
+    position: fixed;
+    bottom: 8vw;
+    width: 80%;
+    height: 10.6667vw;
+    font-size: 4.2667vw;
+    color: white;
+    margin: 0 10%;
+    background-color: #fe4d54;
+    border-radius: 10px;
+  }
+}
+.feedback {
+  width: 100%;
+  //   height: 100vh;
+  //   background-color: #fff;
+
+  // 输入框
+  .section {
+    width: 380px;
+    background: #eeeeee;
+    border-radius: 0.24rem;
+    margin: 0.3rem auto;
+    padding: 0.3rem;
+    position: relative;
+
+    textarea {
+      width: 100%;
+      height: 100%;
+    }
+
+    span {
+      width: 100%;
+      text-align: right;
+      font-size: 12px;
+      font-family: Source Han Sans CN;
+      font-weight: 400;
+      color: #666666;
+      text-align: right;
+      position: absolute;
+      bottom: 0.3rem;
+      right: 0.3rem;
+    }
+  }
+
+  .title {
+    width: 380px;
+    font-size: 14px;
+    font-family: Source Han Sans CN;
+    font-weight: 600;
+    color: #222222;
+    margin: 10px auto;
+  }
+
+  .upload {
+    width: 380px;
+    margin: 10px auto;
+    // background-color: #eeeeee;
+  }
+}
+.add_btn {
+  position: fixed;
+  bottom: 1vh;
+  width: 80%;
+  left: 10vw;
+  --background: #fe4d54;
+  border-radius: 18px;
+}

+ 28 - 0
projects/live-app/src/modules/user/release/release.component.spec.ts

@@ -0,0 +1,28 @@
+/* tslint:disable:no-unused-variable */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { ReleaseComponent } from './release.component';
+
+describe('ReleaseComponent', () => {
+  let component: ReleaseComponent;
+  let fixture: ComponentFixture<ReleaseComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ ReleaseComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ReleaseComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 92 - 0
projects/live-app/src/modules/user/release/release.component.ts

@@ -0,0 +1,92 @@
+import { Component, OnInit } from '@angular/core';
+import * as Parse from 'parse';
+import { ToastController } from '@ionic/angular';
+import { FormsModule } from '@angular/forms';
+import { NavComponent } from '../../../app/components/nav/nav.component';
+import { AuthService } from '../../../services/auth.service';
+import { UploadComponent } from '../../../app/components/upload/upload.component';
+import { ionicStandaloneModules } from '../../ionic-standalone.modules';
+
+@Component({
+  selector: 'app-release',
+  templateUrl: './release.component.html',
+  styleUrls: ['./release.component.scss'],
+  standalone: true,
+  imports: [...ionicStandaloneModules, FormsModule, UploadComponent,NavComponent],
+})
+export class ReleaseComponent implements OnInit {
+  fileList: any = [];
+  content: string = '';
+  inputNum: number = 0;
+  company: string | null = '';
+  constructor(
+    private authServ: AuthService,
+    private toastController: ToastController
+  ) {
+  }
+
+  ngOnInit() {
+  }
+  textChange(e: any) {
+    this.content = e.detail.value;
+    this.inputNum = e.detail.value.length;
+  }
+  onFilesChange(event: any) {
+    console.log(event);
+    this.fileList = event?.map((item: any) => item.url);
+    this.submit()
+  }
+  async submit() {
+    let user = Parse.User.current();
+    if (!user) {
+      this.authServ.logout();
+      return;
+    }
+    console.log(this.fileList);
+    if (
+      (this.content == '' || this.content.trim() == '') &&
+      this.fileList.length < 1
+    ) {
+      await this.presentToast('请填写内容', 1500, 'danger');
+      return;
+    }
+    // let mobile = user.get('mobile');
+    // let Profile = new Parse.Query('Profile');
+    // Profile.equalTo('user', user.id);
+    // Profile.notEqualTo('isDeleted',true)
+    // let profile = await Profile.first();
+    let Feedback = Parse.Object.extend('DramaPost');
+    let feedback = new Feedback();
+    feedback.set('user', {
+      __type: 'Pointer',
+      className: '_User',
+      objectId: user.id,
+    });
+    feedback.set('company', {
+      __type: 'Pointer',
+      className: 'Company',
+      objectId: this.authServ.company,
+    });
+    feedback.set('content', this.content ? this.content : undefined);
+    feedback.set('images', this.fileList);
+    let result = await feedback.save();
+    if (result && result.id) {
+      await this.presentToast('发布成功', 1500, 'success');
+      history.go(-1);
+    } else {
+      await this.presentToast('发布失败', 1500, 'danger');
+      setTimeout(() => {
+        history.go(-1);
+      }, 1500);
+    }
+  }
+
+  async presentToast(title: string, time: number, color: string) {
+    const toast = await this.toastController.create({
+      message: title,
+      duration: time,
+      color: color,
+    });
+    toast.present();
+  }
+}

+ 5 - 1
projects/live-app/src/modules/user/user.modules.routes.ts

@@ -6,6 +6,7 @@ import { BrowseComponent } from './browse/browse.component';
 import { CertificationComponent } from './certification/certification.component';
 import { FeedbackComponent } from './feedback/feedback.component';
 import { ProfileComponent } from './profile/profile.component';
+import { ReleaseComponent } from './release/release.component';
 import { SettingComponent } from './setting/setting.component';
 import { ShareComponent } from './share/share.component';
 const routes: Routes = [
@@ -42,7 +43,10 @@ const routes: Routes = [
     path: 'setting',//设置
     component: SettingComponent,
   },
-  
+  {
+    path: 'release',//设置
+    component: ReleaseComponent,
+  },
 ]
 @NgModule({
   imports: [RouterModule.forChild(routes)],

+ 35 - 2
projects/live-app/src/services/aichart.service.ts

@@ -210,8 +210,8 @@ export class AiChatService {
     query.equalTo('user', Parse.User.current()?.id);
     query.equalTo('invited', uid);
     query.notEqualTo('isDeleted', false);
-    query.equalTo('isAward', true);
-    query.select('objectId');
+    // query.equalTo('isAward', true);
+    query.select('isAward');
     return await query.first();
   }
   /* 获取系统通知 */
@@ -358,4 +358,37 @@ export class AiChatService {
     // 默认返回摩羯座(理论上不会执行到这里)
     return '摩羯座';
   }
+
+  async getPost(limit?: number, skip?: number,uid?: string, ): Promise<any> {
+    let sql = `SELECT "DramaPost"."objectId", "DramaPost".content,"DramaPost".images,
+    us."objectId" uid, us.avatar,us.nickname,"Profile"."identyType",TO_CHAR("DramaPost"."createdAt", 'YYYY-MM-DD HH24:MI') AS formatted_date,
+    (SELECT "isVerify" FROM "DramaPostLog" 
+      WHERE "DramaPostLog"."dramaPost" = "DramaPost"."objectId" 
+      AND "DramaPostLog"."user" = '${Parse.User.current()?.id}'
+      AND "DramaPostLog"."isDeleted" IS NOT TRUE
+      LIMIT 1
+    ) AS "isPostLog",
+    (SELECT COUNT(*) FROM "DramaPostLog" 
+      WHERE "DramaPostLog"."dramaPost" = "DramaPost"."objectId" 
+      AND "DramaPostLog"."isDeleted" IS NOT TRUE
+    ) AS "postCount",
+    (SELECT "objectId" FROM "UserVip" 
+      WHERE "UserVip"."user" = "DramaPost"."user" 
+      AND "UserVip"."isDeleted" IS NOT TRUE
+      AND DATE("UserVip"."expiredAt") >= now()
+    ) AS "isVip"
+    --(CASE WHEN DATE("DramaPost"."createdAt") >= now() THEN true ELSE false END)
+    FROM "DramaPost"
+    LEFT JOIN "_User" as us
+    ON us."objectId" = "DramaPost"."user"
+    LEFT JOIN "Profile"
+    ON "Profile"."user" = "DramaPost"."user"
+    WHERE "DramaPost"."company" = '${this.company}'
+    AND "DramaPost"."isDeleted" IS NOT TRUE
+    ${uid ? `AND "DramaPost"."user" = '${uid}'` : ''}
+    ORDER BY "DramaPost"."createdAt" DESC
+    OFFSET ${skip ?? 0} LIMIT ${limit ?? 10}`
+    let res: any = await this.http.customSQL(sql);
+    return res.data;
+  }
 }