Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:新增文件上传功能 #17

Merged
merged 3 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"format": "prettier --write src/"
},
"dependencies": {
"cos-js-sdk-v5": "^1.6.0",
"element-plus": "^2.5.1",
"pinia": "^2.1.7",
"postcss": "^8.4.33",
Expand Down
49 changes: 49 additions & 0 deletions src/utils/cos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import COS from 'cos-js-sdk-v5'
import { post } from './request'

/*
创建cos(全局唯一的,用来上传文件的) ->
用户需要上传文件-> cos.UploadFile(options,密钥)
-> getAuthorization(options, callback) -> 获取临时密钥
-> callback()将密钥传回UploadFile -> 上传文件
*/

const Bucket = 'cloudmind-1318210890'
const Region = 'ap-guangzhou'
const cos = new COS({
getAuthorization: (options: any, callback: any) => {
// users/md5.suffix 从该字符传中提取md5和suffix
const md5 = options.Key.split('.')[0].split('/').pop()
const suffix = options.Key.split('.')[1]
// options.Key = users/md5.suffix
post('/sts/applySignedUrl', {
md5,
suffix
})
.then((res: any) => {
callback({
TmpSecretId: res.tmpSecretId,
TmpSecretKey: res.tmpSecretKey,
StartTime: res.startTime, // 时间戳,单位秒,如:1580000000
ExpiredTime: res.expiredTime, // 时间戳,单位秒,如:1580000000
ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
SecurityToken: res.sessionToken, // 如果使用临时密钥,需要把 sessionToken 传给 SecurityToken
})
})
}
})

export const cosUploadFile = (file: any, md5: string, suffix: string) => {
cos.uploadFile({
Bucket,
Region,
Key: `users/${md5}${suffix}`,
Body: file,
SliceSize: file.size,
onProgress: (progressData: any) => {
console.log(JSON.stringify(progressData));
}
}, (err: any, data: any) => {
console.log(err || data);
})
}
2 changes: 1 addition & 1 deletion src/utils/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ service.interceptors.response.use(
const longToken = localStorage.getItem('LongToken')

if (longToken) {
post('/auth/refresh', { longToken })
post('/auth/refreshToken', { longToken })
.then((response: any) => {
if (response.msg === 'token有误') {
store.loginOut()
Expand Down
55 changes: 36 additions & 19 deletions src/views/personal/personal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,20 @@
class="contextmenu-popup"
id="contextmenuPopup"
v-show="isContexmenuPopup"
@update="updateFilesList"
:style="{left: popupLeft + 'px', top: popupRight + 'px'}"
></Popup>
<div class="files-box">
<div class="contents">
<div
class="contents"
v-for="(file, index) in filesList"
:key="index"
>
<div class="images">
<i class="iconfont icon-wenjian"></i>
</div>
<div class="title">复习资料</div>
<div class="time">2024/01/26 13:14</div>
<div class="title">{{ getFileName(file.name) }}</div>
<div class="time">{{ getFileTime(file.updateAt) }}</div>
</div>
<!-- <div class="contents">
<div class="images">
Expand Down Expand Up @@ -115,6 +120,7 @@
id="add-popup"
class="add-popup"
v-show="isClickPopup"
@update="updateFilesList"
></Popup>
</footer>
</div>
Expand All @@ -125,15 +131,16 @@
import Nav from '@/components/navigation.vue'
import Search from '@/components/search.vue'
import Popup from '@/views/personal/popup.vue'
import { ref, onMounted } from 'vue'
import { getFilesUrl } from './utils'
import { useStore } from '@/store/index';
import { post } from '@/utils/request';
import type { Ref } from 'vue'
import { ref, onMounted, computed } from 'vue'

const files = ref()
const music = ref()
const images = ref()
const radios = ref()
const store = useStore();
const isFlles = ref(false)
const isImages = ref(false)
const isradios = ref(false)
Expand All @@ -142,29 +149,39 @@ const isClickPopup = ref(false)
const isContexmenuPopup = ref(false)
const path = ref('')
const userId = ref('')
const filesList = ref<any>([])
const popupLeft = ref(0)
const popupRight = ref(0)
const drawerLeft = ref(0)
const contentsMaginLeft = ref(140)
const store = useStore();

onMounted(() => {
userId.value = store.getUserId()
getFilesUrl()
filesList.value = getFilesUrl(userId.value)
console.log(filesList.value);

})

const updateFilesList = (update: boolean) => {
if (update) {
filesList.value = getFilesUrl(userId.value)
}
}

const getFileName = computed(() => {
return (name: string) => {
return name.length > 10 ? name.slice(0, 10) + '...' : name
}
})

const getFilesUrl = () => {
// post('/content/getFile', {
// isGetSize: false,
// filterOptions: {
// onlyUserId: userId.value,
// onlyDocumentType: 1,
// onlyFatherId: userId.value
// }
// })
// .then((res: any) => {
// console.log(res);
// })
const getFileTime = (time: number): string => {
const date = new Date(time * 1000); // 将时间戳转换为日期对象
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0'); // 月份从0开始,需要加1
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
return `${year}/${month}/${day} ${hours}:${minutes}`;
}

const clickShowPopup = () => {
Expand Down
56 changes: 18 additions & 38 deletions src/views/personal/popup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,43 +30,22 @@

<script setup lang="ts">
import SparkMD5 from 'spark-md5'
import mime from 'mime'
import { ref } from 'vue'
import { useStore } from '@/store/index'
import { post, put } from '@/utils/request'
import { post } from '@/utils/request'
import { cosUploadFile } from '@/utils/cos'
import { getTypeFromSuffix, getFatherIdFromHerf } from './utils'
import type { createFiles } from './utils'

const store = useStore();

const uploadToTX = (res: any, suffix: string) => {
// put(res.url, {
// headers: {
// 'Content-Type': mime.getType(suffix),
// 'x-cos-security-token': res.sessionToken
// },
// data: res.data
// })
// .then((response: any) => {
// console.log(response);
// })
}

const applySignedUrl = (md5: string, suffix: string) => {
// post('/sts/applySignedUrl', {
// md5,
// suffix
// })
// .then((res: any) => {
// uploadToTX(res, suffix)
// })
}

const createFilesUrl = (data: Object) => {
// post('/content/createFile', data)
// .then((res: any) => {
// console.log(res);
// })
const emit = defineEmits(['update'])
const createFilesUrl = (data: Object, isSuccess: boolean) => {
post('/content/createFile', data)
.then(() => {
if (isSuccess) {
emit('update', true)
}
})
}

const uploadFiles = (event: any) => {
Expand All @@ -78,25 +57,26 @@ const uploadFiles = (event: any) => {
fileReader.onload = (e: any) => {
spark.append(e.target.result);
const md5 = spark.end();

const suffix = '.' + file.name.split('.').pop();
applySignedUrl(md5, suffix)

const userId = store.getUserId();
const type = getTypeFromSuffix(suffix)
const fatherId = getFatherIdFromHerf() || userId
const createFilesUrlData = ref<createFiles>({
file: {
userId,
name: file.name,
type,
fatherId,
spaceSize: file.size,
md5,
isDel: 1
}
},
})
createFilesUrl(createFilesUrlData)
if (i === event.target.files.length - 1) {
createFilesUrl(createFilesUrlData.value, true)
}
else {
createFilesUrl(createFilesUrlData.value, false)
}
cosUploadFile(file, md5, suffix)
}
}
}
Expand Down
25 changes: 23 additions & 2 deletions src/views/personal/utils.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { useStore } from '@/store/index'
import { post } from '@/utils/request'
import { ref } from 'vue'

export interface createFiles {
file: {
userId: string,
name: string,
type: number, //Type_null = 0; Type_audio = 1; Type_video = 2; Type_photo = 3; Type_word = 4; Type_ppt = 5; Type_zip = 6; Type_excel = 7; Type_pdf = 8; Type_folder = 9; Type_file = 10; Type_code = 11; Type_unknown = 12;
fatherId: string,
spaceSize: number,
md5?: string, //创建文件夹时不填,创建文件时要填
isDel: number, //(默认为1)1:未删除 2:软删除 3:彻底删除
isDel?: number, //(默认为1)1:未删除 2:软删除 3:彻底删除
}
}

Expand All @@ -22,6 +23,26 @@ export const getFatherIdFromHerf = () => {
}
}

export const getFilesUrl = (userId: string) => {
const filesList = ref<any>([])
post('/content/getFileList', {
filterOptions: {
onlyUserId: userId,
onlyDocumentType: 1,
},
paginationOptions: {
page: 1,
limit: 40
}
})
.then((res: any) => {
for (let i = 0; i < res.files.length; i ++) {
filesList.value.push(res.files[i])
}
})
return filesList.value
}

export const getTypeFromSuffix = (suffix: string) => {
const type = suffix.split('.').pop()
switch (type) {
Expand Down
Loading
Loading