mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-28 04:40:37 +00:00
perf: 聊天使用~符号分享文件
This commit is contained in:
parent
ab24ca5b4f
commit
5c25bdfa91
@ -171,15 +171,15 @@ class FileController extends AbstractController
|
||||
$user = User::auth();
|
||||
//
|
||||
$key = trim(Request::input('key'));
|
||||
if (empty($key)) {
|
||||
return Base::retError('请输入关键词');
|
||||
}
|
||||
// 搜索自己的
|
||||
$builder = File::whereUserid($user->userid)->where("name", "like", "%{$key}%");
|
||||
$builder = File::whereUserid($user->userid);
|
||||
if ($key) {
|
||||
$builder->where("name", "like", "%{$key}%");
|
||||
}
|
||||
$array = $builder->take(50)->get()->toArray();
|
||||
// 搜索共享的
|
||||
$take = 50 - count($array);
|
||||
if ($take > 0) {
|
||||
if ($take > 0 && $key) {
|
||||
$list = File::where("name", "like", "%{$key}%")
|
||||
->whereIn('pshare', function ($queryA) use ($user) {
|
||||
$queryA->select('files.id')
|
||||
@ -1102,24 +1102,7 @@ class FileController extends AbstractController
|
||||
return Base::retError('文件夹暂不支持此功能');
|
||||
}
|
||||
//
|
||||
$fileLink = FileLink::whereFileId($file->id)->whereUserid($user->userid)->first();
|
||||
if (empty($fileLink)) {
|
||||
$fileLink = FileLink::createInstance([
|
||||
'file_id' => $file->id,
|
||||
'userid' => $user->userid,
|
||||
'code' => Base::generatePassword(64),
|
||||
]);
|
||||
$fileLink->save();
|
||||
} else {
|
||||
if ($refresh == 'yes') {
|
||||
$fileLink->code = Base::generatePassword(64);
|
||||
$fileLink->save();
|
||||
}
|
||||
}
|
||||
return Base::retSuccess('success', [
|
||||
'id' => $file->id,
|
||||
'url' => Base::fillUrl('single/file/' . $fileLink->code),
|
||||
'num' => $fileLink->num
|
||||
]);
|
||||
$data = FileLink::generateLink($file->id, $user->userid, $refresh == 'yes');
|
||||
return Base::retSuccess('success', $data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Module\Base;
|
||||
|
||||
/**
|
||||
* App\Models\FileLink
|
||||
*
|
||||
@ -34,4 +36,35 @@ class FileLink extends AbstractModel
|
||||
{
|
||||
return $this->hasOne(File::class, 'id', 'file_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成链接
|
||||
* @param $fileId
|
||||
* @param $userid
|
||||
* @param $refresh
|
||||
* @return array
|
||||
*/
|
||||
public static function generateLink($fileId, $userid, $refresh = false)
|
||||
{
|
||||
$fileLink = FileLink::whereFileId($fileId)->whereUserid($userid)->first();
|
||||
if (empty($fileLink)) {
|
||||
$fileLink = FileLink::createInstance([
|
||||
'file_id' => $fileId,
|
||||
'userid' => $userid,
|
||||
'code' => Base::generatePassword(64),
|
||||
]);
|
||||
$fileLink->save();
|
||||
} else {
|
||||
if ($refresh == 'yes') {
|
||||
$fileLink->code = Base::generatePassword(64);
|
||||
$fileLink->save();
|
||||
}
|
||||
}
|
||||
return [
|
||||
'id' => $fileId,
|
||||
'url' => Base::fillUrl('single/file/' . $fileLink->code),
|
||||
'code' => $fileLink->code,
|
||||
'num' => $fileLink->num
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -644,15 +644,47 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
}
|
||||
}
|
||||
}
|
||||
// @成员、#任务
|
||||
// @成员、#任务、~文件
|
||||
preg_match_all("/<span\s+class=\"mention\"(.*?)>.*?<\/span>.*?<\/span>.*?<\/span>/s", $text, $matchs);
|
||||
foreach ($matchs[1] as $key => $str) {
|
||||
preg_match("/data-denotation-char=\"(.*?)\"/", $str, $matchChar);
|
||||
preg_match("/data-id=\"(.*?)\"/", $str, $matchId);
|
||||
preg_match("/data-value=\"(.*?)\"/", $str, $matchValye);
|
||||
$text = str_replace($matchs[0][$key], "[:{$matchChar[1]}:{$matchId[1]}:{$matchValye[1]}:]", $text);
|
||||
$keyId = $matchId[1];
|
||||
if ($matchChar[1] === "~") {
|
||||
if (Base::isNumber($keyId)) {
|
||||
$file = File::permissionFind($keyId);
|
||||
if ($file->type == 'folder') {
|
||||
throw new ApiException('文件夹不支持分享');
|
||||
}
|
||||
$fileLink = FileLink::generateLink($file->id, User::userid());
|
||||
$keyId = $fileLink['code'];
|
||||
} else {
|
||||
preg_match("/\/single\/file\/(.*?)$/i", $keyId, $match);
|
||||
if ($match && strlen($match[1]) >= 32) {
|
||||
$keyId = $match[1];
|
||||
} else {
|
||||
throw new ApiException('文件分享错误');
|
||||
}
|
||||
}
|
||||
}
|
||||
$text = str_replace($matchs[0][$key], "[:{$matchChar[1]}:{$keyId}:{$matchValye[1]}:]", $text);
|
||||
}
|
||||
// 处理链接
|
||||
// 文件分享链接
|
||||
preg_match_all("/(https*:\/\/)((\w|=|\?|\.|\/|&|-|:|\+|%|;|#)+)/i", $text, $matchs);
|
||||
if ($matchs) {
|
||||
foreach ($matchs[0] as $str) {
|
||||
preg_match("/\/single\/file\/(.*?)$/i", $str, $match);
|
||||
if ($match && strlen($match[1]) >= 32) {
|
||||
$file = File::select(['files.id', 'files.name', 'files.ext'])->join('file_links as L', 'files.id', '=', 'L.file_id')->where('L.code', $match[1])->first();
|
||||
if ($file && $file->name) {
|
||||
$name = $file->ext ? "{$file->name}.{$file->ext}" : $file->name;
|
||||
$text = str_replace($str, "[:~:{$match[1]}:{$name}:]", $text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理链接标签
|
||||
preg_match_all("/<a[^>]*?href=([\"'])(.*?)\\1[^>]*?>([^<]*?)<\/a>/is", $text, $matchs);
|
||||
foreach ($matchs[2] as $key => $str) {
|
||||
$herf = $matchs[2][$key];
|
||||
@ -665,6 +697,7 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
$text = preg_replace("/\[:IMAGE:(.*?):(.*?):(.*?):(.*?):(.*?):\]/i", "<img class=\"$1\" width=\"$2\" height=\"$3\" src=\"{{RemoteURL}}$4\" alt=\"$5\"/>", $text);
|
||||
$text = preg_replace("/\[:@:(.*?):(.*?):\]/i", "<span class=\"mention user\" data-id=\"$1\">@$2</span>", $text);
|
||||
$text = preg_replace("/\[:#:(.*?):(.*?):\]/i", "<span class=\"mention task\" data-id=\"$1\">#$2</span>", $text);
|
||||
$text = preg_replace("/\[:~:(.*?):(.*?):\]/i", "<a class=\"mention file\" href=\"{{RemoteURL}}single/file/$1\" target=\"_blank\">~$2</a>", $text);
|
||||
return preg_replace("/^(<p><\/p>)+|(<p><\/p>)+$/i", "", $text);
|
||||
}
|
||||
|
||||
|
||||
@ -225,6 +225,7 @@ export default {
|
||||
userList: null,
|
||||
userCache: null,
|
||||
taskList: null,
|
||||
fileList: {},
|
||||
|
||||
showMore: false,
|
||||
showEmoji: false,
|
||||
@ -414,12 +415,14 @@ export default {
|
||||
this.userList = null;
|
||||
this.userCache = null;
|
||||
this.taskList = null;
|
||||
this.fileList = {};
|
||||
this.$emit('input', this.getInputCache())
|
||||
},
|
||||
taskId() {
|
||||
this.userList = null;
|
||||
this.userCache = null;
|
||||
this.taskList = null;
|
||||
this.fileList = {};
|
||||
this.$emit('input', this.getInputCache())
|
||||
},
|
||||
|
||||
@ -548,7 +551,7 @@ export default {
|
||||
},
|
||||
mention: {
|
||||
allowedChars: /^\S*$/,
|
||||
mentionDenotationChars: ["@", "#"],
|
||||
mentionDenotationChars: ["@", "#", "~"],
|
||||
defaultMenuOrientation: this.defaultMenuOrientation,
|
||||
isolateCharacter: true,
|
||||
positioningStrategy: 'fixed',
|
||||
@ -568,11 +571,12 @@ export default {
|
||||
return "Loading...";
|
||||
},
|
||||
source: (searchTerm, renderList, mentionChar) => {
|
||||
const mentionName = mentionChar == "@" ? 'user-mention' : 'task-mention';
|
||||
const mentionName = mentionChar == "@" ? 'user-mention' : (mentionChar == "#" ? 'task-mention' : 'file-mention');
|
||||
const containers = document.getElementsByClassName("ql-mention-list-container");
|
||||
for (let i = 0; i < containers.length; i++) {
|
||||
containers[i].classList.remove("user-mention");
|
||||
containers[i].classList.remove("task-mention");
|
||||
containers[i].classList.remove("file-mention");
|
||||
containers[i].classList.add(mentionName);
|
||||
$A.scrollPreventThrough(containers[i]);
|
||||
}
|
||||
@ -1223,6 +1227,31 @@ export default {
|
||||
taskCallback([])
|
||||
break;
|
||||
|
||||
case "~": // ~文件
|
||||
this.mentionMode = "file-mention";
|
||||
if ($A.isArray(this.fileList[searchTerm])) {
|
||||
resultCallback(this.fileList[searchTerm])
|
||||
return;
|
||||
}
|
||||
this.fileTimer && clearTimeout(this.fileTimer)
|
||||
this.fileTimer = setTimeout(_ => {
|
||||
this.$store.dispatch("searchFiles", searchTerm).then(({data}) => {
|
||||
this.fileList[searchTerm] = [{
|
||||
label: [{id: 0, value: this.$L('文件分享查看'), disabled: true}],
|
||||
list: data.filter(item => item.type !== "folder").map(item => {
|
||||
return {
|
||||
id: item.id,
|
||||
value: item.ext ? `${item.name}.${item.ext}` : item.name
|
||||
}
|
||||
})
|
||||
}];
|
||||
resultCallback(this.fileList[searchTerm])
|
||||
}).catch(() => {
|
||||
resultCallback([])
|
||||
})
|
||||
}, 300)
|
||||
break;
|
||||
|
||||
default:
|
||||
resultCallback([])
|
||||
break;
|
||||
|
||||
@ -1867,7 +1867,8 @@ export default {
|
||||
this.replyActiveUpdate = true
|
||||
let {text} = this.operateItem.msg
|
||||
if (text.indexOf("mention") > -1) {
|
||||
text = text.replace(/<span class="mention (.*?)" data-id="(\d+)">([@#])(.*?)<\/span>/g, '<span class="mention" data-denotation-char="$3" data-id="$2" data-value="$4"><span contenteditable="false"><span class="ql-mention-denotation-char">$3</span>$4</span></span>')
|
||||
text = text.replace(/<a class="mention file" href="([^'"]*)"([^>]*)>~([^>]*)<\/a>/g, '<span class="mention" data-denotation-char="~" data-id="$1" data-value="$3"><span contenteditable="false"><span class="ql-mention-denotation-char">~</span>$3</span></span>')
|
||||
text = text.replace(/<span class="mention ([^'"]*)" data-id="(\d+)">([@#])([^>]*)<\/span>/g, '<span class="mention" data-denotation-char="$3" data-id="$2" data-value="$4"><span contenteditable="false"><span class="ql-mention-denotation-char">$3</span>$4</span></span>')
|
||||
}
|
||||
this.msgText = $A.formatMsgBasic(text)
|
||||
}
|
||||
|
||||
@ -587,6 +587,10 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.file {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.me {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user