2 Комити 7b7bfe4be1 ... b8194c8a71

Аутор SHA1 Порука Датум
  warrior b8194c8a71 新增版本更新 пре 2 недеља
  warrior 28bcaa09ef 更新礼物和头像显示问题 пре 2 недеља

+ 9 - 0
package-lock.json

@@ -18,6 +18,7 @@
         "@angular/router": "^18.0.0",
         "@capacitor/android": "6.2.0",
         "@capacitor/app": "^6.0.2",
+        "@capacitor/browser": "^6.0.2",
         "@capacitor/camera": "^6.0.0",
         "@capacitor/core": "6.2.0",
         "@capacitor/filesystem": "^6.0.0",
@@ -2304,6 +2305,14 @@
         "@capacitor/core": "^6.0.0"
       }
     },
+    "node_modules/@capacitor/browser": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@capacitor/browser/-/browser-6.0.2.tgz",
+      "integrity": "sha512-mJjdKbpdCAaaDVZD/vjzpJJxL1VvwsGTcEGn+4PpCQyPu3+yNQO7vgjwBV7ZYS6+mZIKeYn5swWq0BFuAcDqFg==",
+      "peerDependencies": {
+        "@capacitor/core": "^6.0.0"
+      }
+    },
     "node_modules/@capacitor/camera": {
       "version": "6.0.0",
       "resolved": "https://registry.npmmirror.com/@capacitor/camera/-/camera-6.0.0.tgz",

+ 1 - 0
package.json

@@ -21,6 +21,7 @@
     "@angular/router": "^18.0.0",
     "@capacitor/android": "6.2.0",
     "@capacitor/app": "^6.0.2",
+    "@capacitor/browser": "^6.0.2",
     "@capacitor/camera": "^6.0.0",
     "@capacitor/core": "6.2.0",
     "@capacitor/filesystem": "^6.0.0",

+ 3 - 0
projects/live-app/src/app/app.component.ts

@@ -9,6 +9,7 @@ import { addIcons } from 'ionicons';
 import * as icons from 'ionicons/icons';
 addIcons(icons)
 import { SafariViewController } from '@ionic-native/safari-view-controller/ngx';
+import { UpdateService } from '../services/update.service';
 @Component({
   selector: 'app-root',
   standalone: true,
@@ -30,10 +31,12 @@ export class AppComponent implements OnInit {
   // }
   constructor(
     private router: Router,
+    private updateServ:UpdateService,
     private backgroundColorService: BackgroundColorService
   ) {
     this.initParseService();
     this.initStatusBar();
+    this.updateServ.updateVersion()
   }
   ngOnInit() {
     // 初始化状态栏背景色

+ 4 - 0
projects/live-app/src/app/app.routes.ts

@@ -11,6 +11,10 @@ import { LoginAuthGuard } from '../modules/login/auth.guard';
 
 export const routes: Routes = [
   { path: '', redirectTo:'tabs', pathMatch: "full",}, // 默认跳转到 ''
+  {
+    path: 'download',
+    loadComponent:()=> import('../modules/download/download.component').then((mod) => mod.DownloadComponent),
+  },
   {
     path: 'invite/:id',
     loadComponent:()=> import('../modules/login/invite/invite.component').then((mod) => mod.InviteComponent),

+ 1 - 1
projects/live-app/src/index.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <head>
   <meta charset="utf-8">
-  <title>LiveApp</title>
+  <title>heychat</title>
   <base href="/">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">

+ 15 - 0
projects/live-app/src/modules/download/download.component.html

@@ -0,0 +1,15 @@
+<ion-content class="download">
+  <div class="logo">
+    <img *ngIf="app?.get('logo')" [src]="app?.get('logo')" alt="" />
+  </div>
+  <div class="block">
+    <div class="li" (click)="downImg(app.get('apkUrl'))">
+      <div class="h3">下载</div>
+      <img class="android" src="img/android.png" alt="" />
+    </div>
+    <div class="li" (click)="downImg(app.get('itunesUrl'))">
+      <div class="h3">下载</div>
+      <img class="ios" src="img/ios.jpg" alt="" />
+    </div>
+  </div>
+</ion-content>

+ 42 - 0
projects/live-app/src/modules/download/download.component.scss

@@ -0,0 +1,42 @@
+.logo {
+  margin: 60px auto 13.333vw auto;
+  text-align: center;
+  .invite-title {
+    margin: 160px auto;
+    font-size: 14px;
+    span {
+      color: #fe4f55;
+      // font-weight: 700;
+      font-size: 18px;
+    }
+  }
+  img {
+    width: 21.333vw;
+    height: 21.333vw;
+    border-radius: 10px;
+  }
+}
+.block {
+  margin: 30px auto;
+  display: flex;
+  flex-direction: column;
+  .li {
+    width: 300px;
+    margin: auto;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    border: 1px solid;
+    margin-bottom: 20px;
+    padding: 10px;
+    height: 80px;
+    .h3 {
+      font-size: 20px;
+      font-weight: bold;
+    }
+    img {
+      width: 200px;
+      // height: 50px;
+    }
+  }
+}

+ 28 - 0
projects/live-app/src/modules/download/download.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 { DownloadComponent } from './download.component';
+
+describe('DownloadComponent', () => {
+  let component: DownloadComponent;
+  let fixture: ComponentFixture<DownloadComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ DownloadComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DownloadComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 38 - 0
projects/live-app/src/modules/download/download.component.ts

@@ -0,0 +1,38 @@
+import { Component, OnInit } from '@angular/core';
+import { ionicStandaloneModules } from '../ionic-standalone.modules';
+import * as Parse from 'parse';
+import { AuthService } from '../../services/auth.service';
+import { CommonModule } from '@angular/common';
+@Component({
+  selector: 'app-download',
+  templateUrl: './download.component.html',
+  styleUrls: ['./download.component.scss'],
+  standalone: true,
+  imports: [
+    ...ionicStandaloneModules,CommonModule
+  ],
+})
+export class DownloadComponent implements OnInit {
+  app:Parse.Object
+
+  constructor(private authServ: AuthService) { }
+
+  async ngOnInit() {
+    let App = new Parse.Query('App');
+    App.equalTo('company', this.authServ.company);
+    this.app = await App.first();
+  }
+  downImg(url:string) {
+    let dlLink: any = document.createElement('a');
+    if ('download' in dlLink) {
+      dlLink.style.visibility = 'hidden';
+      dlLink.href = url;
+      dlLink.download = 'hey聊';
+      document.body.appendChild(dlLink);
+      dlLink.click();
+      document.body.removeChild(dlLink);
+    } else {
+      location.href = url;
+    }
+  }
+}

+ 12 - 0
projects/live-app/src/modules/tabs/my/my.component.scss

@@ -240,6 +240,7 @@
                 width: 100%;
                 height: 100%;
                 border-radius: 50%;
+                object-fit: cover;
               }
             }
           }
@@ -290,10 +291,21 @@
       .row-left {
         display: flex;
         align-items: center;
+        .row-index{
+          width: 18px;
+        }
+        .row-name{
+          overflow: hidden;
+          white-space: nowrap;
+          text-overflow: ellipsis;
+          max-width: 130px;
+        }
         .row-avatar {
           width: 7.6923vw;
           height: 7.6923vw;
           margin: 0 1.0256vw;
+          border-radius: 50%;
+          object-fit: cover;
         }
       }
       .row-right {

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

@@ -379,7 +379,7 @@
         img {
           // width: 10.2564vw;
           height: 17.9487vw;
-          object-fit: cover;
+          object-fit: contain;
           margin-top: 2.5641vw;
         }
       }

+ 24 - 12
projects/live-app/src/modules/user/ranking/ranking.component.scss

@@ -1,4 +1,4 @@
-.content{
+.content {
   .order {
     width: 92.3077vw;
     margin: 2.5641vw auto;
@@ -41,7 +41,7 @@
             color: white;
           }
           .num {
-            color: #fefcc9
+            color: #fefcc9;
           }
           .user-block {
             font-size: 2.5641vw;
@@ -61,6 +61,7 @@
               .avatar {
                 width: 100%;
                 height: 100%;
+                object-fit: cover;
                 border-radius: 50%;
               }
             }
@@ -72,24 +73,24 @@
             color: #fd4800;
           }
         }
-        .user-detail2{
+        .user-detail2 {
           background: #f9bc66;
           width: 100%;
           height: 10.2564vw;
           border-radius: 1.0256vw 0 0 1.0256vw;
         }
-        .user-detail1{
+        .user-detail1 {
           background: #ffc36f;
           width: 100%;
           height: 12.8205vw;
-          border-radius: 1.0256vw 1.0256vw 0 0 ;
+          border-radius: 1.0256vw 1.0256vw 0 0;
           box-shadow: rgba(17, 12, 46, 0.15) 0vw -3.8462vw 25.641vw 0vw;
         }
-        .user-detail3{
+        .user-detail3 {
           background: #fdd7a2;
           width: 100%;
           height: 7.6923vw;
-          border-radius: 0 1.0256vw 1.0256vw 0 ;
+          border-radius: 0 1.0256vw 1.0256vw 0;
         }
       }
     }
@@ -112,10 +113,21 @@
       .row-left {
         display: flex;
         align-items: center;
+        .row-index {
+          width: 18px;
+        }
+        .row-name {
+          overflow: hidden;
+          white-space: nowrap;
+          text-overflow: ellipsis;
+          max-width: 130px;
+        }
         .row-avatar {
           width: 7.6923vw;
           height: 7.6923vw;
           margin: 0 1.0256vw;
+          object-fit: cover;
+          border-radius: 50%;
         }
       }
       .row-right {
@@ -134,18 +146,18 @@
         }
       }
     }
-    .title{
+    .title {
       display: flex;
       justify-content: space-between;
       color: #7d7d7d;
       font-size: 14px;
     }
-    .btns{
+    .btns {
       display: flex;
-      .btn{
+      .btn {
         margin-left: 4px;
       }
-      .btn:hover{
+      .btn:hover {
         color: #ec760c;
       }
     }
@@ -153,4 +165,4 @@
   .user-name {
     text-align: center;
   }
-}
+}

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

@@ -226,7 +226,7 @@ export class AiChatService {
     if (limit) {
       where = `OFFSET ${skip ?? 0} LIMIT ${limit}`;
     }
-    let sql = `SELECT name,image,"gift",COUNT("gift")
+    let sql = `SELECT name,image,"gift",SUM("index") AS "count"
       FROM "LoveRender"
       WHERE "toUser" = '${uid}'
       AND "isDeleted" IS NOT TRUE

+ 127 - 0
projects/live-app/src/services/update.service.ts

@@ -0,0 +1,127 @@
+import { Injectable } from '@angular/core';
+import {
+  Platform,
+  AlertController,
+  LoadingController,
+} from '@ionic/angular';
+import Parse from 'parse';
+import { App } from '@capacitor/app';
+import { Browser } from '@capacitor/browser';
+// import { Diagnostic } from '@awesome-cordova-plugins/diagnostic/ngx';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class UpdateService {
+  versionNumber: any = '';
+  currentVersion: any = '';
+  isAndroid: boolean = false;
+  isIOS: boolean = false;
+  apkUrl: string = 'https://chat.gdchat.cn/release/Android/heychat.apk';
+  itunesUrl: string = 'https://chat.gdchat.cn/download'
+  constructor(
+    private platform: Platform,
+    public alertCtrl: AlertController,
+    public loadingCtrl: LoadingController
+  ) {
+    this.isAndroid = this.platform.is('android');
+    this.isIOS = this.platform.is('ios');
+  }
+  /* 设置本地内存存储 */
+  // async checkPromission() {
+  //   let isAvailable = await this.diagnostic.isExternalStorageAuthorized()
+  //     console.log("permisson_STORAGE:", isAvailable)
+  //     if (!isAvailable) {
+  //       let data = this.diagnostic.requestExternalStorageAuthorization()
+  //     }
+  //   return
+  // }
+  updateVersion() {
+    console.log('updateversion', this.isIOS , this.isAndroid);
+    if (this.platform.is('hybrid') && (this.isIOS || this.isAndroid)) {
+      this.checkUpdate();
+    }
+  }
+  async checkUpdate() {
+    let appInfo = await App.getInfo();
+    let appId = appInfo.id;
+    if (!appId) {
+      appId = 'com.heychat.app';
+    }
+    console.log('update check:', appId);
+    let versionNumber = appInfo.version;
+    Parse.Cloud.run('app_update', { appid: appId}).then(
+      async (res) => {
+        this.versionNumber = Number(
+          '0.' + res.version.toString().replace(new RegExp(/(\.)/g), '0')
+        );
+        this.currentVersion = Number(
+          '0.' + versionNumber.toString().replace(new RegExp(/(\.)/g), '0')
+        );
+        if (res.apkUrl) {
+          this.apkUrl = res.apkUrl;
+        }
+        if (res.downUrl) {
+          this.itunesUrl = res.downUrl;
+        }
+        console.log(this.versionNumber, this.currentVersion);
+        if (this.versionNumber > this.currentVersion) {
+          let buttons = [];
+          if (res.isForce !== true) {
+            buttons.push({
+              text: '取消',
+              handler: async () => {
+                confirm.dismiss();
+              },
+            });
+          }
+          buttons.push({
+            text: '更新',
+            handler: async () => {
+              if (res.isForce == true) {
+                let loading = await this.loadingCtrl.create({
+                  message: '请点下载更新...',
+                  duration: 0,
+                });
+                loading.present();
+              }
+
+              if (this.isAndroid) {
+                this.openUrl(this.apkUrl); // 跳转进入下载页
+              }
+              if (this.isIOS) {
+                this.openUrl(this.itunesUrl);
+              }
+              return true;
+            },
+          });
+          let confirm = await this.alertCtrl.create({
+            header: '新版本更新' + res.version,
+            message: this.getUpdateMessage(res),
+            backdropDismiss: false,
+            buttons: buttons,
+          });
+          confirm.onDidDismiss().then(() => {
+            if (res.isForce == true) {
+              this.checkUpdate();
+            }
+          });
+          confirm.present();
+        } else {
+        }
+      },
+      (err) => {}
+    );
+  }
+
+  getUpdateMessage(res) {
+    if (res?.changelog) {
+      return res?.changelog;
+    } else {
+      return '';
+    }
+  }
+  openUrl = async (url: string) => {
+    await Browser.open({ url: url });
+  };
+}