Browse Source

add upload

warrior 3 months ago
parent
commit
61532da803

+ 6 - 0
package-lock.json

@@ -21,6 +21,7 @@
         "@ionic/angular-toolkit": "^11.0.1",
         "@ionic/core": "^8.4.0",
         "parse": "^5.3.0",
+        "qiniu-js": "^4.0.0-beta.6",
         "rxjs": "~7.8.0",
         "swiper": "^11.1.14",
         "tslib": "^2.3.0",
@@ -10409,6 +10410,11 @@
       "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
       "dev": true
     },
+    "node_modules/qiniu-js": {
+      "version": "4.0.0-beta.6",
+      "resolved": "https://registry.npmmirror.com/qiniu-js/-/qiniu-js-4.0.0-beta.6.tgz",
+      "integrity": "sha512-XNNlgwiEq7wERK+Xew9L+Q7ql0PHV8F4LbW99BWnRSP94IlAP0GQxKiIhgrG7qhDNyjKJop3mYdlWOqbtPxKew=="
+    },
     "node_modules/qjobs": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/qjobs/-/qjobs-1.2.0.tgz",

+ 1 - 0
package.json

@@ -23,6 +23,7 @@
     "@ionic/angular-toolkit": "^11.0.1",
     "@ionic/core": "^8.4.0",
     "parse": "^5.3.0",
+    "qiniu-js": "^4.0.0-beta.6",
     "rxjs": "~7.8.0",
     "swiper": "^11.1.14",
     "tslib": "^2.3.0",

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

@@ -14,6 +14,11 @@ export const routes: Routes = [
     canActivate: mapToCanActivate([AuthGuard]),
     loadChildren: () =>import('../moduls/tabs/tabs.modules.routes').then((mod) => mod.TabsRoutingModule),
   },
+  {
+    path: 'user', 
+    canActivate: mapToCanActivate([AuthGuard]),
+    loadChildren: () =>import('../moduls/user/user.modules.routes').then((mod) => mod.UserRoutingModule),
+  },
   {
     path: 'account', 
     canActivate: mapToCanActivate([AuthGuard]),

+ 23 - 0
projects/live-app/src/app/components/upload/upload.component.html

@@ -0,0 +1,23 @@
+<div
+  class="upload-file"
+  [style.grid-template-columns]="
+    'repeat(' + showBlockNum + ', ' + fileWidth + 'px)'
+  "
+  [style.width]="boxWidth + 'px'"
+>
+  @for (item of fileList; track $index) {
+  <div class="image-content">
+    <img [style.height]="fileHeight + 'px'" [src]="item.url" alt="" />
+    <div class="del" (click)="onDelete($index)"><ion-icon name="close-outline"></ion-icon></div>
+  </div>
+  } @if (fileList.length < maxlenght) {
+  <div class="up-bloak" [style.height]="fileHeight + 'px'">
+    <ion-icon
+      [style.height]="fileHeight - 48 + 'px'"
+      [style.width]="fileHeight - 48 + 'px'"
+      name="cloud-upload-outline"
+    ></ion-icon>
+    <input type="file" multiple (change)="onAdd($event)" accept="image/*" />
+  </div>
+  }
+</div>

+ 46 - 0
projects/live-app/src/app/components/upload/upload.component.scss

@@ -0,0 +1,46 @@
+.upload-file {
+  display: grid;
+  // grid-template-columns: repeat(4, 86px);
+  grid-column-gap: 10px;
+  grid-row-gap: 10px;
+  align-items: center;
+  justify-content: space-evenly;
+  margin: auto;
+  .image-content{
+    position: relative;
+    img{
+      width: 100%;
+      // height: 86px;
+      object-fit: cover;
+    }
+    .del{
+      position: absolute;
+      top: 0px;
+      right: 0;
+      background: #ffffffa8;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+  .up-bloak{
+    width: 100%;
+    // height: 86px;
+    position: relative;
+    background: #f3f3f3;
+    ion-icon{
+      position: absolute;
+      // width: 40px;
+      // height: 40px;
+      top: 24px;
+      left: 24px;
+    }
+    input{
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      z-index: 1;
+      opacity: 0;
+    }
+  }
+}

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

+ 209 - 0
projects/live-app/src/app/components/upload/upload.component.ts

@@ -0,0 +1,209 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { ToastController, IonicModule } from '@ionic/angular';
+import * as Parse from 'parse';
+// import * as qiniu from 'qiniu-js'
+import { createDirectUploadTask, createMultipartUploadV2Task, FileData } from 'qiniu-js';
+@Component({
+  selector: 'app-upload',
+  templateUrl: './upload.component.html',
+  styleUrls: ['./upload.component.scss'],
+  standalone: true,
+  imports: [IonicModule],
+})
+export class UploadComponent implements OnInit {
+  @Input('title') title: string = '上传文件';
+  @Input('files') files: Array<any> = [];
+  @Input('boxWidth') boxWidth: number = 390; //盒子宽度
+  @Input('fileWidth') fileWidth: number = 86; //图片高度
+  @Input('fileHeight') fileHeight: number = 86; //图片宽度
+
+  @Input('maxlenght') maxlenght: number = 1; //文件数量限制
+  @Input('type') type: string = 'file';
+  @Input('size') size: number = 2048; //上传文件限制大小单位KB
+  @Output() change: EventEmitter<any> = new EventEmitter<any>();
+
+  showBlockNum: number = 4; //每行显示数量
+  // uptoken: string = '';
+  // domain: string = '';
+  // bucket: string = '';
+  get accept() {
+    let type;
+    switch (this.type) {
+      case 'image':
+        type = 'image/*';
+        break;
+      case 'pdf':
+        type = 'application/pdf';
+        break;
+      case 'audio':
+        type = 'audio/*';
+        break;
+      case 'video':
+        type = 'video/*';
+        break;
+      default:
+        type = 'file';
+        break;
+    }
+    return type;
+  }
+  disabled: boolean = false;
+  company: string = localStorage.getItem('company') || 'Qje9D4bqol';
+  config: { uptoken: string; domain: string; bucket: string } = {
+    uptoken: '',
+    domain: '',
+    bucket: '',
+  };
+  fileList: any = [
+    // {
+    //   name: 'xxx.png',
+    //   status: 'done',
+    //   url: 'http://www.baidu.com/xxx.png'
+    // },
+  ];
+  Previewfilelist: any; //预览图片数组
+
+  constructor(public toastController: ToastController) {
+    Parse.Cloud.run('qiniu_uptoken', { company: this.company }).then((data) => {
+      this.config = {
+        uptoken: data.uptoken,
+        domain: data.domain,
+        bucket: data.bucket,
+      };
+    });
+  }
+
+  ngOnInit() {
+    /* 计算文件布局 */
+    let n = Math.floor(this.boxWidth / this.fileWidth);
+    console.log(n);
+    console.log(this.boxWidth);
+    if (n * this.fileWidth + (n - 1) * 10 > this.boxWidth) {
+      this.showBlockNum = n - 1;
+    } else {
+      this.showBlockNum = n;
+    }
+    this.fileList = this.files.map((item: any) => {
+      // console.log(item);
+      return {
+        url: item?.url,
+        name: item?.name,
+        type: 'link',
+        status: 'done',
+      };
+    });
+    this.Previewfilelist = this.fileList;
+  }
+  onDelete(index:number){
+    console.log(index);
+    this.fileList.splice(index,1)
+  }
+  async onAdd(e: any) {
+    let files = e.target.files;
+    if (this.fileList.length + files.length > this.maxlenght) {
+      const toast = await this.toastController.create({
+        message: '超出上传文件数量',
+        color: 'warning',
+        duration: 1000,
+      });
+      toast.present();
+      return;
+    }
+    for (let index = 0; index < files.length; index++) {
+      const f = files[index];
+      this.changeFileReader(f);
+    }
+  }
+  //转图片格式
+  changeFileReader(file: any) {
+    return new Promise((res) => {
+      const reader: any = new FileReader();
+      reader.readAsDataURL(file);
+      reader.filename = file.name;
+      console.log(file);
+      // filelist.push(file);
+      // 当文件读取成功时执行的函数
+      let _this = this;
+      reader.onload = async function (e: any) {
+        let size = e.total / 1024; //KB
+        let baseUrl = e.target.result;
+        if (size > _this.size) {
+          const toast = await _this.toastController.create({
+            message: file.name + '文件过大',
+            color: 'warning',
+            duration: 1000,
+          });
+          toast.present();
+          res(true);
+          return;
+        }
+        _this.fileList.push({
+          url: baseUrl,
+          size: size,
+          name: file.name || '未知',
+          type: 'local',
+        });
+        res(true);
+      };
+    });
+  }
+
+  onUpload(){
+    let fs = this.fileList
+    for (let index = 0; index < fs.length; index++) {
+      const f = fs[index];
+      if(f.type == 'local'){
+        console.log(f);
+        this.onQiniuUpFile(f)
+      }
+    }
+    this.change.emit(this.fileList)
+  }
+  onQiniuUpFile(file:any){
+    // return new Promise((resolve, reject) => {
+      // console.log("进入了上传")
+      // const fileData: FileData = { type: 'file', data: file.url}
+      const fileData: FileData = { type: 'string', data: file.url }
+      // const fileData: FileData = { type: 'array-buffer', data: new ArrayBuffer(1e3) }
+      const config = {
+        tokenProvider:async () => {
+         return this.config.uptoken
+        }
+      };
+      createDirectUploadTask(fileData, config).start()
+      .then((result:any) => {
+         // 处理任务完成结果
+         console.log(result);
+         let res = JSON.parse(result.result)
+         console.log(`${this.config.domain}${res.key}`)
+       })
+       .catch((error) => {
+        console.error(error);
+         // 处理任务启动失败错误
+       });
+    //   const observable = qiniu.createDirectUploadTask(file, qiniuFileKey, token, putExtra, config);
+    //   observable.subscribe({
+    //     next: (result) => {
+    //       // 主要用来展示进度
+    //       console.warn(result);
+    //     },
+    //     error: async (err) => {
+    //       // this.$notify('上传图片失败');
+    //       await _this.presentToast(`文件上传失败`, 1500, "danger");
+    //       console.log(err)
+    //       _this.loading.dismiss()
+    //     },
+    //     complete: (res) => {
+    //       console.log("上传完成")
+    //       console.log(res.key);
+    //       console.log(`${_this.domain}${res.key}`)
+    //       resolve(`${_this.domain}${res.key}`)
+    //       _this.loading.dismiss()
+    //     },
+    //   });
+    // }).catch(err => {
+    //   console.log(err)
+    //   _this.loading.dismiss()
+    // })
+  }
+}

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

@@ -1,7 +1,6 @@
 import { NgModule } from '@angular/core';
 import { RouterModule, Routes } from '@angular/router';
 import { BankcardComponent } from './bankcard/bankcard.component';
-import { CertificationComponent } from './certification/certification.component';
 import { WattleComponent } from './wattle/wattle.component';
 const routes: Routes = [
   {
@@ -17,11 +16,6 @@ const routes: Routes = [
     path: 'bankcard',
     component: BankcardComponent,
   },
-  {
-    path: 'idcard',//实名
-    component: CertificationComponent,
-  },
-  
 ]
 @NgModule({
   imports: [RouterModule.forChild(routes)],

+ 1 - 1
projects/live-app/src/moduls/tabs/my/my.component.html

@@ -141,7 +141,7 @@
       </div>
     </div>
     <div class="list">
-      <div class="li" (click)="toUrl('/account/idcard')">
+      <div class="li" (click)="toUrl('/user/idcard')">
         <div class="li-lable">
           <img src="/img/成为主播.png" alt="" class="icon" />
           成为主播

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

@@ -30,7 +30,7 @@ export class MyComponent implements OnInit {
     {
       icon: '/img/相册.png',
       title: '相册',
-      path: '',
+      path: 'user/album',
     },
     {
       icon: '/img/邀请.png',

+ 18 - 0
projects/live-app/src/moduls/user/album/album.component.html

@@ -0,0 +1,18 @@
+<ion-header [translucent]="true" class="header">
+  <ion-toolbar class="toolbar">
+    <ion-buttons slot="start" (click)="back()">
+      <ion-icon
+        name="chevron-back-outline"
+        style="width: 6.4vw; height: 6.4vw; color: #000000"
+      ></ion-icon>
+    </ion-buttons>
+    <ion-title class="title">我的相册</ion-title>
+  </ion-toolbar>
+</ion-header>
+<ion-content class="content">
+  <div class="upload">
+
+    <app-upload (change)="onSave($event)" #upload [maxlenght]="8" [files]="files" [boxWidth]="300" ></app-upload>
+  </div>
+  <ion-button class="add_btn" (click)="upload.onUpload()">保存</ion-button>
+</ion-content>

+ 8 - 0
projects/live-app/src/moduls/user/album/album.component.scss

@@ -0,0 +1,8 @@
+	.add_btn {
+		position: fixed;
+		bottom: 1vh;
+		width: 80%;
+		left: 10vw;
+		background: #92a1ff;
+		border-radius: 18px;
+	}

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

+ 50 - 0
projects/live-app/src/moduls/user/album/album.component.ts

@@ -0,0 +1,50 @@
+import { Component, OnInit } from '@angular/core';
+import { IonicModule, LoadingController, ToastController } from '@ionic/angular';
+import * as Parse from 'parse';
+import { UploadComponent } from '../../../app/components/upload/upload.component';
+
+@Component({
+  selector: 'app-album',
+  templateUrl: './album.component.html',
+  styleUrls: ['./album.component.scss'],
+  standalone: true,
+  imports: [IonicModule,UploadComponent],
+})
+export class AlbumComponent implements OnInit {
+
+  constructor(
+    public loadCtrl: LoadingController,
+    public toastController: ToastController,
+  ) { }
+  files:any = [
+    {
+      url:'https://file-cloud.fmode.cn/Qje9D4bqol/20241108/sj1nf3055728156.png',
+      name:'头像.png',
+    },
+    {
+      url:'https://file-cloud.fmode.cn/Qje9D4bqol/20241108/rrh716055727927.png',
+      name:'头像.png',
+    },
+    {
+      url:'https://file-cloud.fmode.cn/Qje9D4bqol/20241108/cfr128055727439.png',
+      name:'头像.png',
+    },
+    {
+      url:'https://file-cloud.fmode.cn/Qje9D4bqol/20241108/sj1nf3055728156.png',
+      name:'头像.png',
+    },
+    {
+      url:'https://file-cloud.fmode.cn/Qje9D4bqol/20241108/cfr128055727439.png',
+      name:'头像.png',
+    },
+  ]
+  ngOnInit() {
+
+  }
+  onSave(e:any){
+    console.log(e);
+  }
+  back() {
+    history.back()
+  }
+}

+ 0 - 0
projects/live-app/src/moduls/account/certification/certification.component.html → projects/live-app/src/moduls/user/certification/certification.component.html


+ 0 - 0
projects/live-app/src/moduls/account/certification/certification.component.scss → projects/live-app/src/moduls/user/certification/certification.component.scss


+ 0 - 0
projects/live-app/src/moduls/account/certification/certification.component.spec.ts → projects/live-app/src/moduls/user/certification/certification.component.spec.ts


+ 0 - 0
projects/live-app/src/moduls/account/certification/certification.component.ts → projects/live-app/src/moduls/user/certification/certification.component.ts


+ 24 - 0
projects/live-app/src/moduls/user/user.modules.routes.ts

@@ -0,0 +1,24 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { AlbumComponent } from './album/album.component';
+import { CertificationComponent } from './certification/certification.component';
+const routes: Routes = [
+  {
+    path: '',
+    redirectTo:'idcard',
+    pathMatch: "full",
+  },
+  {
+    path: 'idcard',//实名
+    component: CertificationComponent,
+  },
+  {
+    path: 'album',//相册
+    component: AlbumComponent,
+  },
+]
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class UserRoutingModule { }