123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
- import * as Parse from 'parse';
- import * as qiniu from 'qiniu-js';
- import {
- ionicStandaloneModules,
- LoadingController,
- ToastController,
- } from '../../../modules/ionic-standalone.modules';
- @Component({
- selector: 'app-upload',
- templateUrl: './upload.component.html',
- styleUrls: ['./upload.component.scss'],
- standalone: true,
- imports: [...ionicStandaloneModules],
- })
- export class UploadComponent implements OnInit {
- @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 = 'image';
- @Input('size') size: number = 10240; //上传文件限制大小单位KB
- @Input('active') active: boolean = false; //选择文件后主动触发上传
- @Input('multiple') multiple: boolean = false; //是否允许选择多张
- @Output() onChange: EventEmitter<any> = new EventEmitter<any>();
- showBlockNum: number = 4; //每行显示数量
- 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: Array<{
- url: string;
- name: string;
- type: string;
- size?: number;
- file?: any;
- }> = [];
- Previewfilelist: any; //预览图片数组
- loading: any;
- currentPreviewImg: string = '';
- constructor(
- private toastController: ToastController,
- public loadCtrl: LoadingController
- ) {
- 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);
- 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 || item,
- name: item?.name,
- type: 'http',
- // status: 'done',
- };
- });
- this.Previewfilelist = this.fileList;
- }
- onPreview(url: string) {
- this.currentPreviewImg = url;
- }
- onDelete(index: number) {
- console.log(index);
- this.fileList.splice(index, 1);
- this.active && this.onChange.emit(this.fileList);
- }
- 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];
- await this.changeFileReader(f);
- }
- console.log(this.fileList);
- this.active && this.onUpload();
- }
- //转图片格式
- changeFileReader(file: any) {
- return new Promise(async (res) => {
- const windowURL = window.URL || window.webkitURL;
- const src = windowURL.createObjectURL(file);
- let size = file.size / 1024; //KB
- if(size > this.size){
- const toast = await this.toastController.create({
- message: `${file.name || '未知'}超过${Math.ceil(this.size/1024)}MB`,
- color: 'warning',
- duration: 1500,
- });
- toast.present();
- res(true);
- return
- }
- this.fileList.push({
- url: src,
- size: size,
- name: file.name || '未知',
- type: 'local',
- file: file,
- });
- res(true);
- return;
- // const reader: any = new FileReader();
- // reader.readAsDataURL(file);
- // reader.filename = file.name;
- // console.log(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',
- // file: file,
- // });
- // res(true);
- // };
- });
- }
- async onUpload() {
- let authLoad = await this.authSpaceCount();
- if (!authLoad) {
- const toast = await this.toastController.create({
- message: '文件存储空间已满,请联系维护人员。',
- color: 'warning',
- duration: 1000,
- });
- toast.present();
- return;
- }
- let fs = this.fileList;
- this.loading = await this.loadCtrl.create({ message: '上传中' });
- this.loading.present();
- try{
- for (let index = 0; index < fs.length; index++) {
- const f = fs[index];
- if (f.type == 'local') {
- console.log(f);
- let url = await this.onQiniuUpFile(f);
- await this.saveAttachment({
- size: f.size,
- url: url,
- name: f.name,
- type: this.fileList[index].file.type,
- });
- this.fileList[index].url = url;
- this.fileList[index].type = 'http';
- delete this.fileList[index].file;
- delete this.fileList[index].size;
- }
- }
- }catch(err){
- this.loading.dismiss();
- }
- this.onChange.emit(this.fileList);
- this.loading.dismiss();
- }
- /* 校验存储空间 */
- async authSpaceCount(): Promise<boolean> {
- let company = this.company;
- let query = new Parse.Query('Company');
- query.select('configSpace');
- let comObj = await query.get(company);
- let limit = comObj.get('configSpace') && comObj.get('configSpace').limit;
- // return new Promise((res, rej) => {
- let res = await fetch(
- `https://server.fmode.cn/api/storage/space?c=${company}`
- );
- let data = await res.json();
- console.log(data);
- if (data?.code == 200) {
- let spaceMap = data.data;
- let _spaceLimit = this.getLimitBytes(limit);
- let spaceUsed = spaceMap.totalSize;
- console.log('总空间:', _spaceLimit);
- console.log('已用空间:', spaceUsed);
- if (!_spaceLimit || spaceUsed > _spaceLimit) {
- return false;
- }
- return true;
- }
- return false;
- }
- // 单位
- getLimitBytes(limit: string) {
- let u: number = 1024 * 1024 * 1024;
- if (limit) {
- let num = Number(limit.slice(0, limit.length - 2));
- let unit: string = limit.slice(-2);
- switch (unit) {
- case 'EB':
- u = 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
- break;
- case 'PB':
- u = 1024 * 1024 * 1024 * 1024 * 1024;
- break;
- case 'TB':
- u = 1024 * 1024 * 1024 * 1024;
- break;
- case 'GB':
- u = 1024 * 1024 * 1024;
- break;
- case 'MB':
- u = 1024 * 1024;
- break;
- case 'KB':
- u = 1024;
- break;
- default:
- break;
- }
- return num * u;
- }
- return u;
- }
- onQiniuUpFile(file: any): Promise<string> {
- return new Promise((resolve, reject) => {
- console.log('进入了上传');
- let datepath = this.DateFormat(new Date(), 'hhmmss');
- let qiniuFileKey = this.company + '/' + datepath + '/' + file.name;
- const putExtra = {
- // fname: '',
- // params: {},
- // mimeType: this.accept === 'image/*' ? 'image/*' : undefined,
- };
- const config = {
- useCdnDomain: true, //使用cdn加速
- };
- const observable = qiniu.upload(
- file.file,
- qiniuFileKey,
- this.config.uptoken,
- putExtra,
- config
- );
- observable.subscribe({
- next: (result) => {
- // 主要用来展示进度
- console.log('上传===', result);
- },
- error: async (err) => {
- console.error(err);
- const toast = await this.toastController.create({
- message: '上传失败',
- color: 'warning',
- duration: 1000,
- });
- toast.present();
- reject(err);
- },
- complete: (res) => {
- console.log('上传完成');
- console.log(res.key);
- console.log(`${this.config.domain}${res.key}`);
- resolve(`${this.config.domain}${res.key}`);
- // this.loading.dismiss();
- },
- });
- });
- }
- async saveAttachment(
- file: { size?: number; url: string; name: string; type: string },
- cateId?: string
- ) {
- let Attachment = Parse.Object.extend('Attachment');
- let attachment = new Attachment();
- file.size && attachment.set('size', Math.ceil(file.size));
- attachment.set('url', file.url);
- attachment.set('name', file.name);
- attachment.set('mime', file.type);
- attachment.set('company', {
- __type: 'Pointer',
- className: 'Company',
- objectId: this.company,
- });
- cateId &&
- attachment.set('category', {
- __type: 'Pointer',
- className: 'Category',
- objectId: cateId,
- });
- return await attachment.save();
- }
- DateFormat(date: Date, fmt: string) {
- //author: meizz
- let o: any = {
- 'M+': date.getMonth() + 1, //月份
- 'd+': date.getDate(), //日
- 'h+': date.getHours(), //小时
- 'm+': date.getMinutes(), //分
- 's+': date.getSeconds(), //秒
- 'q+': Math.floor((date.getMonth() + 3) / 3), //季度
- S: date.getMilliseconds(), //毫秒
- };
- if (/(y+)/.test(fmt))
- fmt = fmt.replace(
- RegExp.$1,
- (date.getFullYear() + '').substr(4 - RegExp.$1.length)
- );
- for (let k in o)
- if (new RegExp('(' + k + ')').test(fmt))
- fmt = fmt.replace(
- RegExp.$1,
- RegExp.$1.length == 1
- ? o[k]
- : ('00' + o[k]).substr(('' + o[k]).length)
- );
- return fmt;
- }
- }
|