@@ -24,37 +30,68 @@
import { ref, reactive, defineProps, defineEmits } from "vue"
import dayjs from "dayjs";
import { beautifyTime } from '@/utils/datetime'
-import { useDialogueListStore, useDialogueStore, useUserStore } from '@/store'
+import { useDialogueListStore, useDialogueStore, useUserStore,useUploadsStore } from '@/store'
import { useSessionMenu } from '@/hooks'
import photoAlbum from '@/static/image/chatList/photoAlbum.png'
import photoGraph from '@/static/image/chatList/photoGraph.png'
+import videoImg from '@/static/image/chatList/video@2x.png'
import folder from '@/static/image/chatList/folder.png'
import { uploadImg } from '@/api/chat'
import { uniqueId } from '@/utils'
-import { getFileFromUrl } from '@/utils'
-import { getVideoImage } from '@/utils/common'
const props = defineProps({
sendUserInfo: {
type: Object,
default: {},
required: true
+ },
+ talkParams: {
+ type: Object,
+ default: {},
+ required: true
}
});
+const uploadsStore = useUploadsStore()
const { addDialogueRecord, virtualList, updateUploadProgress } = useDialogueListStore()
const dialogueStore = useDialogueStore()
const userStore = useUserStore()
const emit = defineEmits(['selectImg'])
-const onProgressFn = (progress, file, id) => {
+const onProgressFn = (progress, id) => {
console.log(progress.loaded / progress.total * 100, 'progress');
updateUploadProgress(id, progress.loaded / progress.total * 100)
}
-const onUploadImageVideo = async (file, type = 'image') => {
+const photoActionsSelect = (index) => {
+ if (index === 0) {
+ uni.chooseImage({
+ sourceType: ['album'],
+ count: 9,
+ success: async (res) => {
+ console.log(res,'res');
+ res.tempFiles.forEach(async (file) => {
+ let data = await onUploadImageVideo(file, 'image')
+ emit('selectImg', data)
+ })
+ }
+ })
+ }else{
+ uni.chooseVideo({
+ sourceType: ['album'],
+ success: async (res) => {
+ console.log(res,'res');
+ let data = await onUploadImageVideo(res.tempFile, 'video',res.tempFilePath)
+ emit('selectImg', data)
+ }
+ })
+ }
+
+}
+
+const onUploadImageVideo = async (file, type = 'image',fileUrl) => {
console.log(file, 'file');
return new Promise(async (resolve) => {
if (type === 'image') {
@@ -93,7 +130,7 @@ const onUploadImageVideo = async (file, type = 'image') => {
}
virtualList.value.unshift(newItem)
- uploadImg(form, (e, file) => onProgressFn(e, file, randomId)).then(({ status, data, msg }) => {
+ uploadImg(form, (e) => onProgressFn(e, randomId)).then(({ status, data, msg }) => {
if (status == 0) {
resolve({
type: 'image',
@@ -109,55 +146,59 @@ const onUploadImageVideo = async (file, type = 'image') => {
})
}
} else {
- let resp = await getVideoImage(file)
- const form = new FormData()
- form.append('file', file)
- form.append("source", "fonchain-chat");
- form.append("type", "video");
- form.append("urlParam", `width=${resp.width}&height=${resp.height}`);
- let randomId = uniqueId()
- let newItem = {
- avatar: userStore.avatar,
- created_at: dayjs().format('YYYY-MM-DD HH:mm:ss'),
- extra: {
- duration: parseInt(resp.duration),
- height: resp.height,
- name: "",
- url: '',
- cover: resp.url,
- width: resp.width
- },
- float: "right",
- isCheck: false,
- is_mark: 0,
- is_read: 0,
- is_revoke: 0,
- msg_id: randomId,
- msg_type: 5,
- nickname: userStore.nickname,
- receiver_id: dialogueStore.talk.receiver_id,
- sequence: -1,
- talk_type: dialogueStore.talk.talk_type,
- user_id: userStore.uid,
- uploadCurrent: 0,
- uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败
- }
- virtualList.value.unshift(newItem)
- uploadImg(form, (e, file) => onProgressFn(e, file, randomId)).then(({ status, data, msg }) => {
- if (status == 0) {
- console.log(data);
- resolve({
- type: 'video',
- url: data.ori_url,
- cover: data.cover_url,
+ uni.getVideoInfo({
+ src:fileUrl,
+ success:(resp)=>{
+ console.log(resp);
+ form.append('file', file)
+ form.append("source", "fonchain-chat");
+ form.append("type", "video");
+ form.append("urlParam", `width=${resp.width}&height=${resp.height}`);
+ let randomId = uniqueId()
+ let newItem = {
+ avatar: userStore.avatar,
+ created_at: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+ extra: {
duration: parseInt(resp.duration),
- size: file.size
- })
- } else {
- // resolve('')
- // message.error(msg)
+ height: resp.height,
+ name: "",
+ url: fileUrl,
+ width: resp.width
+ },
+ float: "right",
+ isCheck: false,
+ is_mark: 0,
+ is_read: 0,
+ is_revoke: 0,
+ msg_id: randomId,
+ msg_type: 5,
+ nickname: userStore.nickname,
+ receiver_id: dialogueStore.talk.receiver_id,
+ sequence: -1,
+ talk_type: dialogueStore.talk.talk_type,
+ user_id: userStore.uid,
+ uploadCurrent: 0,
+ uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败
+ }
+ virtualList.value.unshift(newItem)
+ uploadImg(form, (e) => onProgressFn(e, randomId)).then(({ status, data, msg }) => {
+ if (status == 0) {
+ console.log(data);
+ resolve({
+ type: 'video',
+ url: data.ori_url,
+ cover: data.cover_url,
+ duration: parseInt(resp.duration),
+ size: file.size
+ })
+ } else {
+ // resolve('')
+ // message.error(msg)
+ }
+ })
}
})
+ const form = new FormData()
}
})
}
@@ -177,9 +218,10 @@ const base64ToFile = (base64) => {
);
}
-const choosePhoto = () => {
+const choosePhoto = (filter = 'none', maximum = 9, multiple = true) => {
window.plus?.gallery.pick((res) => {
console.log(res);
+ res.files.reverse()
res.files.forEach(async (filePath) => {
const suffix = filePath.split('.').pop()?.toLowerCase() || ''
if (['jpg', 'png'].includes(suffix)) {
@@ -203,47 +245,87 @@ const choosePhoto = () => {
}
if (['mp4', 'flv'].includes(suffix)) {
console.log(filePath,"进入视频")
- window.plus?.io?.resolveLocalFileSystemURL(filePath, async (entry) => {
- entry.file((file) => {
- console.log(file,'file');
- const fileReader = new plus.io.FileReader();
- fileReader.readAsDataURL(file);
- fileReader.onloadend = async (e) => {
- const base64Url = e.target.result;
- const fileObj = base64ToFile(base64Url);
- let data = await onUploadImageVideo(fileObj, 'video')
- emit('selectImg', data)
- };
- })
+ // const localUrl = plus.io.convertLocalFileSystemURL(filePath)
+ // console.log(localUrl);
+
+ plus.io.getVideoInfo({
+ filePath:filePath,
+ success:(event)=>{
+ console.log(event);
},
- (err) => {
- console.log(err);
- }
- )
+ fail:(err)=>{
+ console.log(err);
+ }
+ });
+ // window.plus?.io?.resolveLocalFileSystemURL(localUrl, async (entry) => {
+ // entry.file((file) => {
+ // console.log(file,'file');
+ // const fileReader = new plus.io.FileReader();
+ // fileReader.readAsDataURL(file);
+ // fileReader.onloadend = async (e) => {
+ // const base64Url = e.target.result;
+ // const fileObj = base64ToFile(base64Url);
+ // let data = await onUploadImageVideo(fileObj, 'video')
+ // emit('selectImg', data)
+ // };
+ // })
+ // },
+ // (err) => {
+ // console.log(err);
+ // }
+ // )
}
})
}, (err) => {
console.log(err);
},
{
- filter: 'none',
- maximum: 9,
- multiple: true,
+ filter: filter,
+ maximum: maximum,
+ multiple: multiple,
}
)
}
+
+
+
const takePhoto = () => {
}
const chooseFile = () => {
- window.plus?.io.requestFileSystem(
- 3,
- (res) => {
- console.log(res);
- }, (err) => {
- console.log(err);
- },
- )
+ uni.chooseFile({
+ count: 1,
+ extension:[''],
+ success: (res) => {
+ let randomId = uniqueId()
+ let newItem = {
+ avatar: userStore.avatar,
+ created_at: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+ extra: {
+ drive: 3,
+ name: res.tempFiles[0].name,
+ size: res.tempFiles[0].size,
+ path: res.tempFilePaths[0],
+ },
+ float: "right",
+ isCheck: false,
+ is_mark: 0,
+ is_read: 0,
+ is_revoke: 0,
+ msg_id: randomId,
+ msg_type: 6,
+ nickname: userStore.nickname,
+ receiver_id: dialogueStore.talk.receiver_id,
+ sequence: -1,
+ talk_type: dialogueStore.talk.talk_type,
+ user_id: userStore.uid,
+ uploadCurrent: 0,
+ uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败
+ }
+ virtualList.value.unshift(newItem)
+ uploadsStore.initUploadFile(res.tempFiles[0], props.talkParams,randomId)
+ }
+ })
}
@@ -253,7 +335,7 @@ const chooseFile = () => {
.emojiRoot {
width: 100%;
height: 232rpx;
- padding: 20rpx 130rpx 0 130rpx;
+ padding: 20rpx 62rpx 0 62rpx;
display: flex;
justify-content: space-between;
align-items: flex-start;
diff --git a/src/pages/dialog/index.vue b/src/pages/dialog/index.vue
index 49b05fa..299d929 100644
--- a/src/pages/dialog/index.vue
+++ b/src/pages/dialog/index.vue
@@ -15,23 +15,11 @@
-
+
-
+
@@ -64,9 +47,11 @@
'multi-select-check': item.isCheck
}">
-
+
-
-
+
+
+
+
+
actionCopy(item)" class="flex flex-col items-center justify-center">
+
+
复制
+
+
multipleChoose(item)" class="flex flex-col items-center justify-center">
+
+
多选
+
+
actionCite(item)" class="flex flex-col items-center justify-center">
+
+
引用
+
+
actionWithdraw(item)" class="flex flex-col items-center justify-center">
+
+
撤回
+
+
actionDelete(item)" class="flex flex-col items-center justify-center">
+
+
删除
+
+
+
+
+
-
-
-
-
+
+
+
已选中:
+
{{ selectedMessage.length }}条消息
+
+
+
+
diff --git a/src/pages/index/components/chatItem.vue b/src/pages/index/components/chatItem.vue
index e3e5d52..9d764c2 100644
--- a/src/pages/index/components/chatItem.vue
+++ b/src/pages/index/components/chatItem.vue
@@ -4,7 +4,7 @@
-
+
diff --git a/src/static/image/chatList/cite@2x.png b/src/static/image/chatList/cite@2x.png
new file mode 100644
index 0000000..6c0ab67
Binary files /dev/null and b/src/static/image/chatList/cite@2x.png differ
diff --git a/src/static/image/chatList/copy07@2x.png b/src/static/image/chatList/copy07@2x.png
new file mode 100644
index 0000000..fee2cfe
Binary files /dev/null and b/src/static/image/chatList/copy07@2x.png differ
diff --git a/src/static/image/chatList/delete@2x.png b/src/static/image/chatList/delete@2x.png
new file mode 100644
index 0000000..2d7902d
Binary files /dev/null and b/src/static/image/chatList/delete@2x.png differ
diff --git a/src/static/image/chatList/multipleChoices@2x.png b/src/static/image/chatList/multipleChoices@2x.png
new file mode 100644
index 0000000..92ef375
Binary files /dev/null and b/src/static/image/chatList/multipleChoices@2x.png differ
diff --git a/src/static/image/chatList/video@2x.png b/src/static/image/chatList/video@2x.png
new file mode 100644
index 0000000..692be55
Binary files /dev/null and b/src/static/image/chatList/video@2x.png differ
diff --git a/src/static/image/chatList/withdraw@2x.png b/src/static/image/chatList/withdraw@2x.png
new file mode 100644
index 0000000..8a7cc28
Binary files /dev/null and b/src/static/image/chatList/withdraw@2x.png differ
diff --git a/src/static/image/chatList/zu6050@2x.png b/src/static/image/chatList/zu6050@2x.png
new file mode 100644
index 0000000..e6de970
Binary files /dev/null and b/src/static/image/chatList/zu6050@2x.png differ
diff --git a/src/static/image/chatList/zu6051@2x.png b/src/static/image/chatList/zu6051@2x.png
new file mode 100644
index 0000000..406c577
Binary files /dev/null and b/src/static/image/chatList/zu6051@2x.png differ
diff --git a/src/static/image/chatList/zu6052@2x.png b/src/static/image/chatList/zu6052@2x.png
new file mode 100644
index 0000000..2e84b37
Binary files /dev/null and b/src/static/image/chatList/zu6052@2x.png differ
diff --git a/src/static/image/chatList/zu6053@2x.png b/src/static/image/chatList/zu6053@2x.png
new file mode 100644
index 0000000..d13881f
Binary files /dev/null and b/src/static/image/chatList/zu6053@2x.png differ
diff --git a/src/store/auth/index.js b/src/store/auth/index.js
index cd26d7e..2e06a2d 100644
--- a/src/store/auth/index.js
+++ b/src/store/auth/index.js
@@ -4,7 +4,7 @@ import {uniStorage} from "@/utils/uniStorage.js"
import {ref} from 'vue'
export const useAuth = createGlobalState(() => {
// const token = useStorage('token', '', uniStorage)
- const token = ref('30119d9978a6f3321fb4779c0040e997df4dd0dd0cf6b71119657617d2249ed783f940b0050d5be7e758740ea467afdf3eeb4d28fb5ea234af60ebe51fb218ff6a0563074f3084b41c1bc8dc0733d06bfbb433a8d5a1d13eb6227adbf50a5da566a4cacdbf91899e563f10864fe2acfe8edb3a186766d1fb247c2e3c6bb3c014a610243d87b0460c692d5bea2442fe553a9cf98e29ff7be27c364ab2047c67957e28df8f7cdd90366fd8f94967d5f8e037fab5f9e3c3a342f4830875841d5a4361ab087bd4205321e6ad9db918811786bd9e1be7df913383eef6f47f436073ca')
+ const token = ref('30119d9978a6f3321fb4779c0040e997df4dd0dd0cf6b71119657617d2249ed783f940b0050d5be7e758740ea467afdf3eeb4d28fb5ea234af60ebe51fb218ff6a0563074f3084b41c1bc8dc0733d06bfbb433a8d5a1d13eb6227adbf50a5da566a4cacdbf91899e563f10864fe2acfeee36e90ceb1aa03bbcca63f1bf5514d416827d0ea543bd8e02552fbd612d801b4b827977f6fe7d6201838456049083706a6e48004fc0ad99eddea3a8875f6583e959fd172a7cfb40f877bc0741a259520e9b6f524d04ee175bdc99c32eef4ef52c1ed38ed1034df8695c62ff44933644')
const refreshToken = useStorage('refreshToken', '', uniStorage)
const userInfo = useStorage('userInfo', {}, uniStorage)
const leaderList = useStorage('leaderList', [], uniStorage)
diff --git a/src/store/modules/dialogue.js b/src/store/modules/dialogue.js
index 9c852b9..373ba78 100644
--- a/src/store/modules/dialogue.js
+++ b/src/store/modules/dialogue.js
@@ -56,7 +56,11 @@ export const useDialogueStore = defineStore('dialogue', {
read_sequence: 0, // 当前已读的最后一条记录
records: []
}
- }
+ },
+ // 转发消息类型
+ forwardType: 1,
+ // 合并转发消息
+ forwardMessages: []
}
},
getters: {
@@ -164,6 +168,11 @@ export const useDialogueStore = defineStore('dialogue', {
}
},
+ // 设置多选模式
+ setMultiSelect(value) {
+ this.isOpenMultiSelect = value
+ },
+
// 关闭多选模式
closeMultiSelect() {
this.isOpenMultiSelect = false
@@ -214,7 +223,8 @@ export const useDialogueStore = defineStore('dialogue', {
ServePublishMessage(data).then((res) => {
if (res.code == 200) {
- this.closeMultiSelect()
+ // this.closeMultiSelect()
+ message.success('转发成功')
}
})
},
@@ -226,6 +236,14 @@ export const useDialogueStore = defineStore('dialogue', {
useEditorStore().loadUserEmoticon()
message && message.success('收藏成功')
})
+ },
+ // 设置转发消息类型
+ setForwardType(type) {
+ this.forwardType = type
+ },
+ // 设置合并转发消息
+ setForwardMessages(messages) {
+ this.forwardMessages = messages
}
}
})
diff --git a/src/store/modules/dialogueList.js b/src/store/modules/dialogueList.js
index 789c114..59286fd 100644
--- a/src/store/modules/dialogueList.js
+++ b/src/store/modules/dialogueList.js
@@ -52,6 +52,25 @@ export const useDialogueListStore = createGlobalState(() => {
}
}
+ const updateDialogueRecord=(record)=>{
+ const dialogue = lodash.cloneDeep(useDialogueStore())
+ const item = getDialogueList(dialogue.index_name)
+ const recordIndex = item.records.findIndex(item=>item.msg_id===record.msg_id)
+ if(recordIndex!==-1){
+ item.records[recordIndex] = {
+ ...item.records[recordIndex],
+ ...record
+ }
+ }
+ const virtualIndex = virtualList.value.findIndex(item=>item.msg_id===record.msg_id)
+ if(virtualIndex!==-1){
+ virtualList.value[virtualIndex] = {
+ ...virtualList.value[virtualIndex],
+ ...record
+ }
+ }
+ }
+
const deleteDialogueRecord=(record)=>{
const dialogue = lodash.cloneDeep(useDialogueStore())
const item = getDialogueList(dialogue.index_name)
@@ -89,11 +108,12 @@ export const useDialogueListStore = createGlobalState(() => {
zpagingRef,
getDialogueList,
addDialogueRecord,
+ updateDialogueRecord,
deleteDialogueRecord,
updateUploadProgress,
updateZpagingRef,
zpagingComplete,
addChatRecord,
- virtualList
+ virtualList,
}
})
diff --git a/src/store/modules/uploads.ts b/src/store/modules/uploads.ts
index 0451d7b..219d036 100644
--- a/src/store/modules/uploads.ts
+++ b/src/store/modules/uploads.ts
@@ -1,9 +1,11 @@
import { defineStore } from 'pinia'
import { ServeFindFileSplitInfo, ServeFileSubareaUpload } from '@/api/upload'
import { ServeSendTalkFile } from '@/api/chat'
+import { useDialogueListStore } from '@/store/modules/dialogueList'
// @ts-ignore
const message = window.$message
+const {updateUploadProgress} = useDialogueListStore()
// 处理拆分上传文件
function fileSlice(file: File, uploadId: string, eachSize: number) {
@@ -47,7 +49,8 @@ export const useUploadsStore = defineStore('uploads', {
},
// 初始化上传
- initUploadFile(file: File, talkType: number, receiverId: number, username: string) {
+ initUploadFile(file: File, talkParams: any, msgId: string) {
+ const {type:talkType,receiver_id:receiverId,username} = talkParams;
ServeFindFileSplitInfo({
file_name: file.name,
file_size: file.size
@@ -69,7 +72,7 @@ export const useUploadsStore = defineStore('uploads', {
username: username
})
- this.triggerUpload(upload_id)
+ this.triggerUpload(upload_id,msgId)
this.isShow = true
} else {
message.error(res.message)
@@ -83,7 +86,7 @@ export const useUploadsStore = defineStore('uploads', {
},
// 触发上传
- triggerUpload(uploadId: string) {
+ triggerUpload(uploadId: string,msgId: string) {
const item = this.findItem(uploadId)
const form = item.files[item.uploadIndex]
@@ -98,11 +101,18 @@ export const useUploadsStore = defineStore('uploads', {
if (item.uploadIndex === item.files.length) {
item.status = 2
item.percentage = 100
+ console.log(msgId,'msgId');
+
+ updateUploadProgress(msgId,100)
this.sendUploadMessage(item)
} else {
const percentage = (item.uploadIndex / item.files.length) * 100
item.percentage = percentage.toFixed(1)
- this.triggerUpload(uploadId)
+ console.log(msgId,'msgId');
+ console.log(percentage,'percentage');
+
+ updateUploadProgress(msgId,percentage)
+ this.triggerUpload(uploadId,msgId)
}
} else {
item.status = 3
diff --git a/src/utils/common.js b/src/utils/common.js
index 512ac2d..48b6287 100644
--- a/src/utils/common.js
+++ b/src/utils/common.js
@@ -167,7 +167,7 @@ export function getVideoImage(file, time = 1) {
video.autoplay = true
video.muted = true
- video.oncanplay = () => {
+ video.onloadeddata = () => {
let canvas = document.createElement('canvas')
canvas.width = video.videoWidth
canvas.height = video.videoHeight
diff --git a/src/utils/index.js b/src/utils/index.js
index 84789fe..51c3e36 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -144,7 +144,7 @@ export const getFileType = (url) => {
export const getFileFromUrl = (url, fileName) => {
return new Promise(async(resolve, reject) => {
const osName = uni.getSystemInfoSync().osName;
- if (osName === "android") {
+ // if (osName === "android") {
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
@@ -165,12 +165,12 @@ export const getFileFromUrl = (url, fileName) => {
};
// 发送
xhr.send();
- }else{
- const response = await fetch(url);
- const blob = await response.blob();
- const file = new File([blob], fileName, { type: getFileType(url) });
- resolve(file);
- }
+ // }else{
+ // const response = await fetch(url);
+ // const blob = await response.blob();
+ // const file = new File([blob], fileName, { type: getFileType(url) });
+ // resolve(file);
+ // }
});
}
diff --git a/src/utils/upload/auth.js b/src/utils/upload/auth.js
index b869dc5..14277d4 100644
--- a/src/utils/upload/auth.js
+++ b/src/utils/upload/auth.js
@@ -1,6 +1,8 @@
import { storage } from './storage'
+import { useAuth } from '@/store/auth'
const AccessToken = 'AUTH_TOKEN'
+const {token} = useAuth()
/**
* 验证是否登录
@@ -17,7 +19,7 @@ export function isLoggedIn() {
* @returns token
*/
export function getAccessToken() {
- return storage.get(AccessToken) || ''
+ return token.value || ''
}
/**
diff --git a/src/utils/upload/request.js b/src/utils/upload/request.js
index 963d1cd..a84e0ec 100644
--- a/src/utils/upload/request.js
+++ b/src/utils/upload/request.js
@@ -4,7 +4,7 @@ import { delAccessToken, getAccessToken } from '@/utils/upload/auth'
// 创建 axios 实例
const request = axios.create({
// API 请求的默认前缀
- baseURL: import.meta.env.VITE_BASE_API,
+ baseURL: import.meta.env.VITE_BASEURL,
// 请求超时时间
timeout: 10000
@@ -21,7 +21,7 @@ const errorHandler = (error) => {
// 判断是否是响应错误信息
if (error.response) {
if (error.response.status == 401) {
- delAccessToken()
+ // delAccessToken()
if (!once) {
once = true