diff --git a/app/Models/ReportLink.php b/app/Models/ReportLink.php new file mode 100644 index 000000000..12a4a5d0e --- /dev/null +++ b/app/Models/ReportLink.php @@ -0,0 +1,86 @@ +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 + ]; + } +} diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php index 825746df5..89ab2d20c 100644 --- a/app/Models/WebSocketDialogMsg.php +++ b/app/Models/WebSocketDialogMsg.php @@ -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", "@$2", $text); $text = preg_replace("/\[:#:(.*?):(.*?):\]/is", "#$2", $text); $text = preg_replace("/\[:~:(.*?):(.*?):\]/i", "~$2", $text); + $text = preg_replace("/\[:%:(.*?):(.*?):\]/i", "%$2", $text); $text = preg_replace("/\[:QUICK:(.*?):(.*?):\]/i", "$2", $text); return preg_replace("/^(

<\/p>)+|(

<\/p>)+$/i", "", $text); } diff --git a/database/migrations/2025_03_15_164703_create_report_links_table.php b/database/migrations/2025_03_15_164703_create_report_links_table.php new file mode 100644 index 000000000..a0b1cd136 --- /dev/null +++ b/database/migrations/2025_03_15_164703_create_report_links_table.php @@ -0,0 +1,35 @@ +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'); + } +} diff --git a/resources/assets/js/pages/manage/components/DialogWrapper.vue b/resources/assets/js/pages/manage/components/DialogWrapper.vue index 9f64aef6f..98ee6b2f0 100644 --- a/resources/assets/js/pages/manage/components/DialogWrapper.vue +++ b/resources/assets/js/pages/manage/components/DialogWrapper.vue @@ -3340,8 +3340,14 @@ export default { this.$refs.input.setText(text) } else { if (text.indexOf("mention") > -1) { - text = text.replace(/]*)>~([^>]*)<\/a>/g, '~$3') - text = text.replace(/([@#])([^>]*)<\/span>/g, '$3$4') + text = text.replace( + /]*>([~%])([^>]*)<\/a>/g, + '$3$4' + ) + text = text.replace( + /([@#])([^>]*)<\/span>/g, + '$3$4' + ) } text = text.replace(/]*>/gi, match => { return match.replace(/(width|height)="\d+"\s*/ig, ""); diff --git a/resources/assets/sass/dark.scss b/resources/assets/sass/dark.scss index 99dfdfb77..63c8ff486 100644 --- a/resources/assets/sass/dark.scss +++ b/resources/assets/sass/dark.scss @@ -274,7 +274,9 @@ body.dark-mode-reverse { color: #000000; &.file, - &[data-denotation-char="~"] { + &.report, + &[data-denotation-char="~"], + &[data-denotation-char="%"] { color: #0027a1 !important; } } diff --git a/resources/assets/sass/pages/components/dialog-wrapper.scss b/resources/assets/sass/pages/components/dialog-wrapper.scss index 50c276fae..6b39af888 100644 --- a/resources/assets/sass/pages/components/dialog-wrapper.scss +++ b/resources/assets/sass/pages/components/dialog-wrapper.scss @@ -1513,7 +1513,9 @@ } &.file, - &[data-denotation-char="~"] { + &.report, + &[data-denotation-char="~"], + &[data-denotation-char="%"] { color: #436FF6 !important; }