feat: 支持使用%发送工作报告

This commit is contained in:
kuaifan 2025-03-15 16:52:40 +08:00
parent 75db81f2f9
commit 021c09e426
6 changed files with 148 additions and 4 deletions

86
app/Models/ReportLink.php Normal file
View File

@ -0,0 +1,86 @@
<?php
namespace App\Models;
use App\Exceptions\ApiException;
use App\Module\Base;
/**
* App\Models\ReportLink
*
* @property int $id
* @property int|null $rid 报告ID
* @property int|null $num 累计访问
* @property string|null $code 链接码
* @property int|null $userid 会员ID
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \App\Models\Report|null $report
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelAppend()
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelHidden()
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel change($array)
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink query()
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel remove()
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink whereCode($value)
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink whereNum($value)
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink whereRid($value)
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|ReportLink whereUserid($value)
* @mixin \Eloquent
*/
class ReportLink extends AbstractModel
{
/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function report(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(Report::class, 'id', 'report_id');
}
/**
* 生成链接
* @param $rid
* @param $userid
* @param $refresh
* @return array
*/
public static function generateLink($rid, $userid, $refresh = false)
{
$report = Report::find($rid);
if (empty($report)) {
throw new ApiException('报告不存在或已被删除');
}
if ($report->userid != $userid) {
if (!ReportReceive::whereRid($rid)->whereUserid($userid)->exists()) {
throw new ApiException('您没有权限查看该报告');
}
}
$reportLink = ReportLink::whereRid($rid)->whereUserid($userid)->first();
if (empty($reportLink)) {
$reportLink = ReportLink::createInstance([
'rid' => $rid,
'userid' => $userid,
'code' => base64_encode("{$rid},{$userid}," . Base::generatePassword()),
]);
$reportLink->save();
} else {
if ($refresh == 'yes') {
$reportLink->code = base64_encode("{$rid},{$userid}," . Base::generatePassword());
$reportLink->save();
}
}
return [
'id' => $rid,
'url' => Base::fillUrl('single/report/detail/' . $reportLink->code),
'code' => $reportLink->code,
'num' => $reportLink->num
];
}
}

View File

@ -962,6 +962,18 @@ class WebSocketDialogMsg extends AbstractModel
throw new ApiException('文件分享错误');
}
}
} elseif ($matchChar[1] === "%") {
if (Base::isNumber($keyId)) {
$reportLink = ReportLink::generateLink($keyId, User::userid());
$keyId = $reportLink['code'];
} else {
preg_match("/\/single\/report\/detail\/(.*?)$/i", $keyId, $match);
if ($match && strlen($match[1]) >= 8) {
$keyId = $match[1];
} else {
throw new ApiException('报告分享错误');
}
}
}
$text = str_replace($matchs[0][$key], "[:{$matchChar[1]}:{$keyId}:{$matchValye[1]}:]", $text);
}
@ -1044,6 +1056,7 @@ class WebSocketDialogMsg extends AbstractModel
$text = preg_replace("/\[:@:(.*?):(.*?):\]/i", "<span class=\"mention user\" data-id=\"$1\">@$2</span>", $text);
$text = preg_replace("/\[:#:(.*?):(.*?):\]/is", "<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);
$text = preg_replace("/\[:%:(.*?):(.*?):\]/i", "<a class=\"mention report\" href=\"{{RemoteURL}}single/report/detail/$1\" target=\"_blank\">%$2</a>", $text);
$text = preg_replace("/\[:QUICK:(.*?):(.*?):\]/i", "<span data-quick-key=\"$1\">$2</span>", $text);
return preg_replace("/^(<p><\/p>)+|(<p><\/p>)+$/i", "", $text);
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateReportLinksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('report_links', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('rid')->nullable()->default(0)->index()->comment('报告ID');
$table->integer('num')->nullable()->default(0)->comment('累计访问');
$table->string('code')->nullable()->default('')->comment('链接码');
$table->bigInteger('userid')->nullable()->default(0)->index()->comment('会员ID');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('report_links');
}
}

View File

@ -3340,8 +3340,14 @@ export default {
this.$refs.input.setText(text)
} else {
if (text.indexOf("mention") > -1) {
text = text.replace(/<a class="mention file" href="([^'"]*)"([^>]*)>~([^>]*)<\/a>/g, '<span class="mention" data-denotation-char="~" data-id="$1" data-value="$3">&#xFEFF;<span contenteditable="false"><span class="ql-mention-denotation-char">~</span>$3</span>&#xFEFF;</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">&#xFEFF;<span contenteditable="false"><span class="ql-mention-denotation-char">$3</span>$4</span>&#xFEFF;</span>')
text = text.replace(
/<a class="mention ([^'"]*)" href="([^'"]*)"[^>]*>([~%])([^>]*)<\/a>/g,
'<span class="mention" data-denotation-char="$3" data-id="$2" data-value="$4">&#xFEFF;<span contenteditable="false"><span class="ql-mention-denotation-char">$3</span>$4</span>&#xFEFF;</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">&#xFEFF;<span contenteditable="false"><span class="ql-mention-denotation-char">$3</span>$4</span>&#xFEFF;</span>'
)
}
text = text.replace(/<img[^>]*>/gi, match => {
return match.replace(/(width|height)="\d+"\s*/ig, "");

View File

@ -274,7 +274,9 @@ body.dark-mode-reverse {
color: #000000;
&.file,
&[data-denotation-char="~"] {
&.report,
&[data-denotation-char="~"],
&[data-denotation-char="%"] {
color: #0027a1 !important;
}
}

View File

@ -1513,7 +1513,9 @@
}
&.file,
&[data-denotation-char="~"] {
&.report,
&[data-denotation-char="~"],
&[data-denotation-char="%"] {
color: #436FF6 !important;
}