<template>
|
<view class="uni-project-event-log">
|
<scroll-view class="msg-list" :scroll-top="scrollTop" scroll-y="true" @scroll="onScroll">
|
<LogItem v-for="(item, index) in msgBody" :key="item.ID" :playMsgid="playId" :msgData="item"
|
@playVoice="playVoice" @playVideo="playVideo" @previewImage="previewImage">
|
</LogItem>
|
</scroll-view>
|
</view>
|
</template>
|
|
<script>
|
import TaskInit from "@/common/extend.js"
|
import LogItem from "@/components/log-item.vue"
|
import {
|
logGetAnalysisList as prjEventLogGetAnalysisList,
|
logAdd as prjEventLogAdd
|
|
} from "@/api/gungho/prjevent.js"
|
import {
|
uploadFile,
|
downloadFileUrl,
|
publicFileUrl,
|
downloadFileTask
|
} from "@/api/index.js"
|
import {
|
showModal,
|
showToast,
|
getGuid
|
} from "@/common/Page.js"
|
import {
|
DOMParser
|
} from "xmldom"
|
|
export default {
|
name: "pageProjectEventLog",
|
components: {
|
LogItem,
|
},
|
props: {
|
eventId: {
|
type: String,
|
default () {
|
return "";
|
}
|
},
|
logType: {
|
type: String,
|
default () {
|
return "";
|
}
|
},
|
playId: {
|
type: String,
|
default () {
|
return "";
|
}
|
},
|
isMobilePlatform: {
|
type: Boolean,
|
default () {
|
return false;
|
}
|
},
|
|
|
},
|
data() {
|
return {
|
safeAreaBottom: getApp().globalData.safeAreaBottom,
|
|
msgBody: [],
|
msgSendBody: [],
|
msgImages: [],
|
msgLastDate: "",
|
scrollTop: 0,
|
old: {
|
scrollTop: 0,
|
focusInput: false,
|
},
|
}
|
|
},
|
mounted() {
|
|
},
|
watch: {
|
|
},
|
methods: {
|
setData: function(obj) {
|
let that = this;
|
let keys = [];
|
let val, data;
|
|
Object.keys(obj).forEach(function(key) {
|
keys = key.split(".");
|
val = obj[key];
|
data = that.$data;
|
keys.forEach(function(key2, index) {
|
if (index + 1 == keys.length) {
|
that.$set(data, key2, val);
|
} else {
|
if (!data[key2]) {
|
that.$set(data, key2, {});
|
}
|
}
|
data = data[key2];
|
});
|
});
|
},
|
loadData() {
|
this.msgBody = []
|
this.msgImages = []
|
this.msgLastDate = ""
|
this.loadWorkLog().then((resData) => {
|
this.msgBody = resData || [];
|
this.$nextTick(function() {
|
this.scrollTop = 2000000
|
});
|
}).catch((ex) => {
|
this.$emit("loadFail")
|
})
|
|
},
|
getLogImage(data) {
|
var _this = this
|
_this.msgImages = []
|
if (Array.isArray(data)) {
|
for (let log = 0; log < data.length; log++) {
|
let logs = data[log];
|
logs.imgurl = _this.getUserImage(logs.Creator)
|
if (logs.Content) {
|
let sDesc = logs.Content
|
sDesc = sDesc.replace(/ /g, "")
|
let arr = sDesc.match(new RegExp(/<img[\s\S]*>/, 'g'))
|
if (arr) {
|
// console.log("getLogImage arr",arr)
|
for (let i = 0; i < arr.length; i++) {
|
let xmlDoc = new DOMParser().parseFromString(arr[i], "text/xml");
|
let finds = xmlDoc.getElementsByTagName('img'); //获取find节点
|
for (let i = 0; i < finds.length; i++) { //循环节点
|
let finder = finds[i];
|
let src = finder.getAttribute("src")
|
if (src)
|
_this.msgImages.push(src)
|
}
|
}
|
}
|
}
|
}
|
}
|
//console.log("getLogImage",_this.msgImages)
|
return data;
|
},
|
|
async getLogData(log) {
|
|
var _this = this
|
const app = getApp()
|
if (app.globalData.userdata.user_login == log.Creator)
|
log.self = true;
|
else
|
log.self = false;
|
|
log.imgurl = _this.getUserImage(log.Creator)
|
|
//判断是否是音频
|
log.isMedia = false
|
let sContent = log.Content
|
let sContent2 = log.Content
|
|
//console.log("Content:",sContent)
|
sContent = sContent.replace(/<audio[\s\S]*>/, '')
|
sContent2 = sContent2.replace(/<video[\s\S]*>/, '')
|
|
//console.log("Content replace res:",sContent)
|
if (sContent == "") {
|
let xmlDoc = new DOMParser().parseFromString(log.Content, "text/xml");
|
let finds = xmlDoc.getElementsByTagName('audio'); //获取find节点
|
for (let i = 0; i < finds.length; i++) { //循环节点
|
let finder = finds[i];
|
let src = finder.getAttribute("src")
|
let len = finder.getAttribute("length")
|
let fileserver = finder.getAttribute("data-fileserver")
|
let src2 = await publicFileUrl(fileserver, src)
|
// console.log("Content audio src:",src)
|
log.mediaSrc = src2
|
log.mediaLen = parseInt(len)
|
log.mediaType = "audio"
|
log.mediaWidth = 100
|
log.mediaHeight = 20
|
log.mediaPoster = ""
|
break;
|
}
|
log.isMedia = true
|
//row.msg.voice.length = 03
|
} else if (sContent2 == "") {
|
let xmlDoc = new DOMParser().parseFromString(log.Content, "text/xml");
|
let finds = xmlDoc.getElementsByTagName('video'); //获取find节点
|
for (let i = 0; i < finds.length; i++) { //循环节点
|
let finder = finds[i];
|
let src = finder.getAttribute("src")
|
let len = finder.getAttribute("length")
|
let width = finder.getAttribute("width")
|
let height = finder.getAttribute("height")
|
let poster = finder.getAttribute("poster")
|
let fileserver = finder.getAttribute("data-fileserver")
|
let src2 = await publicFileUrl(fileserver, src)
|
|
let poster2 = poster ? await publicFileUrl(fileserver, poster) : ""
|
// console.log("Content audio src:",src)
|
let nW = width
|
let nH = height
|
if (nH > 160) {
|
nH = 160
|
nW = (width * 160) / (height)
|
}
|
log.mediaSrc = src2
|
log.mediaLen = parseInt(len)
|
log.mediaType = "video"
|
log.mediaWidth = nW
|
log.mediaHeight = nH
|
log.mediaPoster = poster2
|
break;
|
}
|
log.isMedia = true
|
//row.msg.voice.length = 03
|
} else {
|
|
const imgRegex =
|
/<img[^>]+src="([^">]+)"[^>]*data-fileserver="([^">]+)"[^>]*>/g;
|
|
let arr = log.Content.match(imgRegex)
|
if (arr) {
|
for (let i = 0; i < arr.length; i++) {
|
const xmlImg = arr[i]
|
let xmlDoc = new DOMParser().parseFromString(xmlImg, "text/xml");
|
let finds = xmlDoc.getElementsByTagName('img'); //获取find节点
|
for (let j = 0; j< finds.length;j++) { //循环节点
|
let finder = finds[j];
|
let src = finder.getAttribute("src")
|
let fileserver = finder.getAttribute("data-fileserver")
|
let src2 = await publicFileUrl(fileserver, src)
|
log.Content = log.Content.replace(xmlImg,
|
`<img style="width:auto;height:auto;max-width:100%;max-height:160px;display:block;" src="${src2}"/>`
|
);
|
break
|
}
|
|
}
|
}
|
log.isMedia = false
|
}
|
|
return log
|
|
},
|
|
async getLogDefault(data) {
|
|
var _this = this
|
if (Array.isArray(data)) {
|
let resData = []
|
const app = getApp()
|
for (let log = 0; log < data.length; log++) {
|
let logs = data[log];
|
|
let curLogIndex = _this.msgBody.findIndex((logTemp, index, arr) => {
|
return logTemp.ID == logs.ID;
|
})
|
if (curLogIndex == -1) {
|
let timeCreate = new Date()
|
if (logs.CreateTime)
|
timeCreate = TaskInit.dateUtils.parse(logs.CreateTime)
|
logs.time = TaskInit.dateUtils.toShortTimeString(timeCreate)
|
let date = TaskInit.dateUtils.toDateString(timeCreate)
|
logs.date = TaskInit.dateUtils.openinfo_formatter_ttime(date, "")
|
if (_this.msgLastDate == logs.date) {
|
logs.date = ""
|
} else {
|
_this.msgLastDate = logs.date
|
}
|
logs = await _this.getLogData(logs)
|
resData.push(logs);
|
}
|
}
|
|
return resData;
|
} else
|
return await this.getLogData(data);
|
|
},
|
//装载讨论记录
|
async loadWorkLog() {
|
|
var _this = this;
|
return new Promise(async (resolve, rej) => {
|
try {
|
const param = {
|
id: _this.eventId,
|
type: this.logType || "",
|
isasc: 1,
|
}
|
const res = await prjEventLogGetAnalysisList(param)
|
if (res) {
|
const list = _this.getLogDefault(res || []);
|
_this.getLogImage(list)
|
resolve(list)
|
}
|
} catch (ex) {
|
this.showError(ex)
|
rej(ex)
|
console.log(" prjEventLogGetAnalysisList failed", ex)
|
|
|
}
|
|
|
})
|
},
|
formatNewDiscuzMsg(msg) {
|
var _this = this;
|
msg.self = true
|
const app = getApp()
|
msg.Creator = app.globalData.userdata.user_login
|
msg.CreatorName = app.globalData.userdata.user_name
|
msg.imgurl = _this.getUserImage(msg.Creator)
|
let timeCreate = new Date()
|
if (msg.CreateTime)
|
timeCreate = TaskInit.dateUtils.parse(msg.CreateTime)
|
|
msg.time = TaskInit.dateUtils.toShortTimeString(timeCreate)
|
msg.date = "今天"
|
if (this.msgLastDate == msg.date) {
|
msg.date = ""
|
} else {
|
this.msgLastDate = msg.date
|
}
|
msg.isMedia = false
|
if (msg.Content) {
|
let sContent = msg.Content
|
let sContent2 = msg.Content
|
let sContent3 = msg.Content
|
//console.log("Content:",sContent)
|
sContent = sContent.replace(/<audio[\s\S]*>/, '')
|
sContent2 = sContent2.replace(/<video[\s\S]*>/, '')
|
sContent3 = sContent3.replace(/<img[\s\S]*>/, '')
|
//console.log("Content replace res:",sContent)
|
if (sContent == "") {
|
let xmlDoc = new DOMParser().parseFromString(msg.Content, "text/xml");
|
let finds = xmlDoc.getElementsByTagName('audio'); //获取find节点
|
for (let i = 0; i < finds.length; i++) { //循环节点
|
let finder = finds[i];
|
let src = finder.getAttribute("src")
|
let len = finder.getAttribute("length")
|
msg.mediaSrc = src
|
// if (!msg.failedMsg && !msg.sendingMsg) {
|
// let fileserver = finder.getAttribute("data-fileserver")
|
// let src2 = await publicFileUrl(fileserver, src)
|
// msg.mediaSrc = src2
|
// }
|
msg.mediaLen = parseInt(len)
|
msg.mediaType = "audio"
|
msg.mediaWidth = 100
|
msg.mediaHeight = 20
|
msg.mediaPoster = ""
|
break;
|
}
|
msg.isMedia = true
|
//row.msg.voice.length = 03
|
} else if (sContent2 == "") {
|
let xmlDoc = new DOMParser().parseFromString(msg.Content, "text/xml");
|
let finds = xmlDoc.getElementsByTagName('video'); //获取find节点
|
for (let i = 0; i < finds.length; i++) { //循环节点
|
let finder = finds[i];
|
let src = finder.getAttribute("src")
|
let len = finder.getAttribute("length")
|
let width = finder.getAttribute("width")
|
let height = finder.getAttribute("height")
|
let poster = finder.getAttribute("poster")
|
msg.mediaSrc = src
|
msg.mediaPoster = poster
|
let nW = width
|
let nH = height
|
if (nH > 160) {
|
nH = 160
|
nW = (width * 160) / (height)
|
}
|
msg.mediaLen = parseInt(len)
|
msg.mediaType = "video"
|
msg.mediaWidth = nW
|
msg.mediaHeight = nH
|
|
break;
|
}
|
msg.isMedia = true
|
} else {
|
msg.isMedia = false
|
}
|
}
|
|
console.log("formatNewDiscuzMsg", msg)
|
return msg
|
},
|
|
addTaskDiscuzMsg(guid, msgText) {
|
var _this = this;
|
return new Promise(function(resolve, reject) {
|
if (msgText.length < 1) {
|
resolve("")
|
return
|
}
|
|
prjEventLogAdd({
|
id: _this.eventId,
|
optype: _this.logType,
|
content: msgText
|
}).then((res) => {
|
_this.setSendMsgSuccess(guid, res, msgText)
|
resolve("")
|
}).catch((rej) => {
|
console.log("addTaskDiscuzMsg taskLogAdd failed", rej)
|
_this.setSendMsgFailed(guid)
|
_this.showError(rej)
|
reject("")
|
})
|
})
|
},
|
async setSendMsgSuccess(guid, guidNew, sText) {
|
|
let dataBody = this.msgBody
|
let curIndex = dataBody.findIndex((task, index, arr) => {
|
return task.ID == guid;
|
})
|
let msgTemp = {}
|
let app = getApp()
|
msgTemp.ID = guidNew
|
msgTemp.Creator = app.globalData.userdata.user_login
|
msgTemp.CreatorName = app.globalData.userdata.user_name
|
let timeCreate = new Date()
|
msgTemp.time = TaskInit.dateUtils.toShortTimeString(timeCreate)
|
msgTemp.date = "今天"
|
if (this.msgLastDate == msgTemp.date) {
|
msgTemp.date = ""
|
} else {
|
this.msgLastDate = msgTemp.date
|
}
|
msgTemp.failedMsg = false
|
msgTemp.sendingMsg = false
|
msgTemp.Content = sText
|
msgTemp = await this.getLogData(msgTemp)
|
if (curIndex == -1) {
|
dataBody.push(msgTemp)
|
} else {
|
|
dataBody[curIndex] = msgTemp
|
}
|
this.setData({
|
msgBody: dataBody
|
})
|
|
},
|
setSendMsgFailed(guid) {
|
let dataBody = this.msgBody
|
let curIndex = dataBody.findIndex((task, index, arr) => {
|
return task.ID == guid;
|
})
|
if (curIndex != -1) {
|
let msgTemp = dataBody[curIndex]
|
msgTemp.failedMsg = true
|
msgTemp.sendingMsg = false
|
dataBody[curIndex] = msgTemp
|
this.setData({
|
msgBody: dataBody
|
})
|
}
|
},
|
updateSendMsgFileProgress(guid, percent) {
|
if (percent < 0 || percent > 99)
|
return
|
let dataBody = this.msgBody
|
let curIndex = dataBody.findIndex((task, index, arr) => {
|
return task.ID == guid;
|
})
|
if (curIndex != -1) {
|
let msgTemp = dataBody[curIndex]
|
msgTemp.sendingMsg = true
|
msgTemp.percentSend = percent
|
// msgTemp = this.formatNewDiscuzMsg(msgTemp)
|
dataBody[curIndex] = msgTemp
|
this.setData({
|
msgBody: dataBody
|
})
|
}
|
},
|
|
getFileMD5(filePath, cbSuccess, cbFail) {
|
// #ifdef MP-WEIXIN
|
uni.getFileSystemManager().getFileInfo({
|
filePath,
|
digestAlgorithm: "md5",
|
success: (res) => {
|
if (typeof cbSuccess == "function") {
|
cbSuccess({
|
md5: res.digest,
|
size: res.size
|
})
|
|
}
|
},
|
fail: (res) => {
|
if (typeof cbSuccess == "function") {
|
cbFail(res)
|
|
}
|
}
|
})
|
// #endif
|
// #ifndef MP-WEIXIN
|
uni.getFileInfo({
|
filePath,
|
digestAlgorithm: "md5",
|
success: (res) => {
|
if (typeof cbSuccess == "function") {
|
cbSuccess({
|
md5: res.digest,
|
size: res.size
|
})
|
|
}
|
},
|
fail: (res) => {
|
if (typeof cbFail == "function") {
|
cbFail(res)
|
}
|
}
|
})
|
// #endif
|
},
|
uploadThumb(filePath, cbSuccess, cbFail) {
|
const _this = this;
|
this.getFileMD5(filePath, (resSuc) => {
|
|
const file = {
|
path: filePath,
|
md5: resSuc.md5,
|
size: resSuc.size,
|
public: true
|
}
|
let aaa = filePath.split('/');
|
if (aaa.length > 0) {
|
file.name = aaa[aaa.length - 1]
|
} else
|
file.name = aname
|
|
uploadFile(file, async (docSuc2) => {
|
try {
|
if (typeof cbSuccess == "function") {
|
cbSuccess(docSuc2)
|
}
|
} catch (ex) {
|
if (typeof cbFail == "function") {
|
cbFail(docFail)
|
}
|
}
|
|
}, (docFail) => {
|
if (typeof cbFail == "function") {
|
cbFail(docFail)
|
}
|
})
|
|
|
}, (resFail) => {
|
if (typeof cbFail == "function") {
|
cbFail(resFail)
|
}
|
})
|
|
},
|
|
uploadTaskMsgFile(guid, msg, isDel = false) {
|
const _this = this;
|
msg.public = true
|
uploadFile(msg, (docSuc) => {
|
let imgMsg = ''
|
if (msg.type == 'video') {
|
|
if (msg.thumb == "") {
|
imgMsg =
|
`<video controls src="${docSuc.url}" data-fileserver="${docSuc.filesflag}" length="${msg.length}" width="${msg.width}" height="${msg.height}"/>`
|
_this.addTaskDiscuzMsg(guid, imgMsg)
|
|
} else {
|
uploadThumb(msg.thumb, (docSuc2) => {
|
imgMsg =
|
`<video controls src="${docSuc.url}" poster="${docSuc2.url}" data-fileserver="${docSuc2.filesflag}" length="${msg.length}" width="${msg.width}" height="${msg.height}"/>`
|
_this.addTaskDiscuzMsg(guid, imgMsg)
|
|
}, (docFail) => {
|
imgMsg =
|
`<video controls src="${docSuc.url}" data-fileserver="${docSuc.filesflag}" length="${msg.length}" width="${msg.width}" height="${msg.height}"/>`
|
_this.addTaskDiscuzMsg(guid, imgMsg)
|
})
|
}
|
} else if (msg.type == 'audio') {
|
imgMsg =
|
`<audio controls src="${docSuc.url}" data-fileserver="${docSuc.filesflag}" length="${msg.length}"/>`
|
_this.addTaskDiscuzMsg(guid, imgMsg).then(() => {
|
if (isDel) {
|
uni.removeSavedFile({
|
filePath: path
|
})
|
}
|
})
|
} else if (msg.type == 'image') {
|
imgMsg =
|
`<img src="${docSuc.url}" data-fileserver="${docSuc.filesflag}" />`
|
|
_this.addTaskDiscuzMsg(guid, imgMsg).then(() => {})
|
} else {
|
_this.setSendMsgFailed(guid)
|
|
}
|
}, (docProgress, uploadTask) => {
|
_this.updateSendMsgFileProgress(guid, docProgress.progress)
|
},
|
(docFail) => {
|
console.log("uploadAttach uploadFile fail", docFail);
|
_this.setSendMsgFailed(guid)
|
}
|
)
|
},
|
//上传媒体
|
async uploadTaskMedia(msg, isDel = false) {
|
const _this = this;
|
let path = msg.path
|
let length = msg.length || 0
|
let bBigFile = false
|
let guid = getGuid();
|
let imgMsg = ''
|
if (msg.type == 'video') {
|
imgMsg = '<video src="' + path + '" poster="' + msg.thumb + '" width="' + msg
|
.width +
|
'" height="' +
|
msg.height + '" length="' + length + '"/>'
|
} else if (msg.type == 'audio') {
|
imgMsg = '<audio src="' + path + '" length="' + length + '" />'
|
} else if (msg.type == 'image') {
|
imgMsg =
|
'<img style="width:auto;height:auto;max-width:100%;max-height:160px;display:block;" alt="" src="' +
|
path + '" />'
|
} else {
|
return
|
}
|
let dataBody = _this.msgBody
|
let msgTemp = {}
|
msgTemp.ID = guid
|
msgTemp.failedMsg = false
|
msgTemp.sendingMsg = true
|
msgTemp.Content = imgMsg
|
msgTemp.percentSend = 0
|
msgTemp = await _this.formatNewDiscuzMsg(msgTemp)
|
dataBody.push(msgTemp)
|
this.setData({
|
msgBody: dataBody
|
})
|
this.getFileMD5(msg.path, (resSuc) => {
|
msg.md5 = resSuc.md5
|
msg.size = resSuc.size
|
_this.uploadTaskMsgFile(guid, msg, isDel)
|
}, (resFail) => {
|
_this.setSendMsgFailed(guid)
|
})
|
|
|
},
|
|
//解析需要上传的媒体文件
|
uploadMedias(tempFiles, isDel = false) {
|
let _this = this;
|
for (let i = 0; i < tempFiles.length; i++) {
|
let itemFile = tempFiles[i]
|
if (itemFile.tempFilePath)
|
itemFile.path = itemFile.tempFilePath
|
let aname = itemFile.path || itemFile.filePath || ""
|
if (itemFile.name)
|
aname = itemFile.name
|
let aaa = aname.split('/');
|
if (aaa.length > 0) {
|
itemFile.name = aaa[aaa.length - 1]
|
} else
|
itemFile.name = aname
|
|
let msg = {
|
type: itemFile.fileType,
|
size: itemFile.size,
|
path: itemFile.path,
|
name: itemFile.name,
|
length: 0,
|
}
|
if (itemFile.fileType == "image") {
|
_this.uploadTaskMedia(msg, isDel)
|
} else if (itemFile.fileType == "audio") {
|
msg.length = itemFile.duration
|
_this.uploadTaskMedia(msg, isDel)
|
} else if (itemFile.fileType == "video") {
|
msg.thumb = itemFile.thumbTempFilePath || ""
|
msg.width = itemFile.width
|
msg.height = itemFile.height
|
_this.uploadTaskMedia(msg, isDel)
|
} else {
|
showModal(itemFile.tempFilePath + '是未知类型,不能作为任务交流内容发送', '提示', false)
|
continue;
|
}
|
|
}
|
|
},
|
//获取用户头像
|
getUserImage(userID) {
|
return `${getApp().globalData.apiurl.org}/userphoto?login=${userID}`;
|
},
|
onScroll(e) {
|
this.old.scrollTop = e.detail.scrollTop
|
},
|
|
scrollBottom() {
|
this.scrollTop = this.old.scrollTop
|
this.$nextTick(function() {
|
this.scrollTop = 2000000
|
});
|
|
},
|
// 播放语音
|
playVoice(e) {
|
this.$emit("playVoice", e)
|
},
|
// 播放视频
|
playVideo(e) {
|
|
uni.navigateTo({
|
url: "/pages/common/videoPage?url=" + encodeURIComponent(e.mediaSrc)
|
})
|
},
|
// 预览图片
|
previewImage(e) {
|
uni.previewImage({
|
current: e,
|
urls: this.msgImages,
|
})
|
},
|
showError(ex) {
|
let tip = typeof ex == 'string' ? ex : typeof ex.err_msg == 'string' ? ex.err_msg :
|
typeof ex
|
.errMsg ==
|
'string' ? ex.errMsg : ""
|
showModal(tip, "提示", false)
|
},
|
}
|
}
|
</script>
|
|
<style lang="less">
|
.uni-project-event-log {
|
display: flex;
|
width: 100%;
|
height: 100%;
|
|
.msg-list {
|
display: flex;
|
width: 750rpx;
|
background-color: transparent;
|
flex-direction: column !important;
|
}
|
}
|
</style>
|