add spoiler tag + fix attendance additional rewards

This commit is contained in:
xiaomlove
2022-04-12 01:48:22 +08:00
parent 1c065fdf65
commit 58abda6d1a
18 changed files with 149 additions and 52 deletions

View File

@@ -118,24 +118,13 @@ class Test extends Command
// $r = $searchRep->deleteBookmark(1);
// $r = $searchRep->addBookmark(1);
// $rep = new AttendanceRepository();
// $uid = 1;
// $attendance = $rep->getAttendance($uid);
$rep = new AttendanceRepository();
$uid = 1;
$attendance = $rep->getAttendance($uid);
// $r = $rep->migrateAttendanceLogs($uid);
// $r = $rep->getContinuousDays($attendance);
// $r = $rep->getContinuousPoints(30);
// $today = Carbon::today();
// $tomorrow = Carbon::tomorrow();
// $yesterday = Carbon::parse('+10 days');
// dd($today->diffInDays($yesterday));
// $r = get_smile(12);
// dd($r);
// $key = "dddd1";
// $model = \App\Models\TorrentSecret::query()->where('id', 1)->first();
// \Nexus\Database\NexusDB::cache_put($key, $model);
$peer = new Peer(['last_action' => '2022-04-08 22:20:14']);
$r = $rep->getContinuousPoints(11);
dd($r);
}

View File

@@ -40,9 +40,9 @@ class AttendanceRepository extends BaseRepository
$diffDays = $today->diffInDays($added);
if ($diffDays == 1) {
//yesterday do it, it's continuous
do_log("[CONTINUOUS]");
$continuousDays = $this->getContinuousDays($attendance);
$points = $this->getContinuousPoints($continuousDays);
$continuousDays = $this->getContinuousDays($attendance, Carbon::yesterday());
$points = $this->getContinuousPoints($continuousDays + 1);
do_log("[CONTINUOUS] continuous days from yesterday: $continuousDays, points: $points");
$update = [
'added' => $now,
'points' => $points,
@@ -93,10 +93,10 @@ class AttendanceRepository extends BaseRepository
$step = $settings['attendance_step'] ?? Attendance::STEP_BONUS;
$max = $settings['attendance_max'] ?? Attendance::MAX_BONUS;
$extraAwards = $settings['attendance_continuous'] ?? Attendance::CONTINUOUS_BONUS;
$points = min($initial + $days * $step, $max);
$points = min($initial + ($days - 1) * $step, $max);
krsort($extraAwards);
foreach ($extraAwards as $key => $value) {
if ($days >= $key - 1) {
if ($days == $key) {
$points += $value;
break;
}
@@ -248,14 +248,10 @@ class AttendanceRepository extends BaseRepository
return $insertCount;
}
public function getContinuousDays(Attendance $attendance, $start = ''): int
public function getContinuousDays(Attendance $attendance, $start): int
{
if (!empty($start)) {
$start = Carbon::parse($start);
} else {
$start = $attendance->added;
}
$logQuery = $attendance->logs()->where('date', '<=', $start)->orderBy('date', 'desc');
$start = Carbon::parse($start);
$logQuery = $attendance->logs()->where('date', '<=', $start->format('Y-m-d'))->orderBy('date', 'desc');
$attendanceLogs = $logQuery->get(['date'])->keyBy('date');
$counts = $attendanceLogs->count();
do_log(sprintf('user: %s, log counts: %s from query: %s', $attendance->uid, $counts, last_query()));
@@ -269,9 +265,9 @@ class AttendanceRepository extends BaseRepository
$checkDate = $value->format('Y-m-d');
if ($attendanceLogs->has($checkDate)) {
$days++;
do_log(sprintf('user: %s, date: %s, has attendance, now days: %s', $attendance->uid, $checkDate, $days));
do_log(sprintf('user: %s, date: %s, [HAS_ATTENDANCE], now days: %s', $attendance->uid, $checkDate, $days));
} else {
do_log(sprintf('user: %s, date: %s, not attendance, now days: %s', $attendance->uid, $checkDate, $days));
do_log(sprintf('user: %s, date: %s, [NOT_ATTENDANCE], now days: %s', $attendance->uid, $checkDate, $days));
break;
}
}
@@ -286,24 +282,24 @@ class AttendanceRepository extends BaseRepository
}
$attendance = $this->getAttendance($user->id);
if (!$attendance) {
throw new \LogicException("Haven't attendance yet");
throw new \LogicException(nexus_trans('attendance.have_not_attendance_yet'));
}
$date = Carbon::createFromTimestampMs($timestampMs);
$now = Carbon::now();
if ($date->gte($now) || $now->diffInDays($date) > Attendance::MAX_RETROACTIVE_DAYS) {
throw new \LogicException(sprintf("date: %s can't be retroactive attend", $date->format('Y-m-d')));
throw new \LogicException(nexus_trans('attendance.target_date_can_no_be_retroactive', ['date' => $date->format('Y-m-d')]));
}
return NexusDB::transaction(function () use ($user, $attendance, $date) {
if (AttendanceLog::query()->where('uid', $user->id)->where('date', $date->format('Y-m-d'))->exists()) {
throw new \RuntimeException("Already attendance");
throw new \RuntimeException(nexus_trans('attendance.already_attendance'));
}
if ($user->attendance_card < 1) {
throw new \RuntimeException("Attendance card not enough");
throw new \RuntimeException(nexus_trans('attendance.card_not_enough'));
}
$log = sprintf('user: %s, card: %s, retroactive date: %s', $user->id, $user->attendance_card, $date->format('Y-m-d'));
$continuousDays = $this->getContinuousDays($attendance, $date->clone()->subDay(1));
$log .= ", continuousDays: $continuousDays";
$points = $this->getContinuousPoints($continuousDays);
$continuousDays = $this->getContinuousDays($attendance, $date->clone()->subDays(1));
$log .= ", continuousDays from prev day: $continuousDays";
$points = $this->getContinuousPoints($continuousDays + 1);
$log .= ", points: $points";
do_log($log);
$userUpdates = [

View File

@@ -262,6 +262,36 @@ function formatYoutube($src, $width = '', $height = ''): string
$width, $height, $videoId
));
}
function formatSpoiler($content, $title = '', $defaultCollapsed = true): string
{
global $lang_functions;
if (!$title) {
$title = $lang_functions['spoiler_default_title'];
}
$content = str_replace(['<br>', '<br />'], '', $content);
$contentClass = "spoiler-content";
if ($defaultCollapsed) {
$contentClass .= " collapse";
}
$HTML = sprintf(
'<div><div><div class="spoiler-title" title="%s">%s</div></div><div class="%s"><pre>%s</pre></div></div>',
$lang_functions['spoiler_expand_collapse'], $title, $contentClass, $content
);
$js = <<<JS
jQuery('.spoiler-title').on('click', function () {
let content = jQuery(this).parent().next();
if (content.hasClass('collapse')) {
content.height(content[0].scrollHeight).removeClass('collapse')
} else {
content.height(0).addClass('collapse')
}
})
JS;
\Nexus\Nexus::js($js, 'footer', false, 'spoiler');
return addTempCode($HTML);
}
function format_urls($text, $newWindow = false) {
// return preg_replace("/((https?|ftp|gopher|news|telnet|mms|rtsp):\/\/[^()\[\]<>\s]+)/ei", "formatUrl('\\1', ".($newWindow==true ? 1 : 0).", '', 'faqlink')", $text);
return preg_replace_callback("/((https?|ftp|gopher|news|telnet|mms|rtsp):\/\/[^()\[\]<>\s]+)/i", function ($matches) use ($newWindow) {
@@ -350,6 +380,12 @@ function format_comment($text, $strip_html = true, $xssclean = false, $newtab =
return formatYoutube($matches[4], $matches[2], $matches[3]);
}, $s);
}
//[spoiler=What happens to the hero?]The hero dies at the end![/spoiler]
if (str_contains($s, '[spoiler')) {
$s = preg_replace_callback("/\[spoiler(=(.*))?\](.+?)\[\/spoiler\]/is", function ($matches) {
return formatSpoiler($matches[3], $matches[2], nexus()->getScript() != 'preview');
}, $s);
}
// [url=http://www.example.com]Text[/url]
if ($adid) {
@@ -2202,7 +2238,7 @@ function menu ($selected = "home") {
else
print ("<li" . ($selected == "forums" ? " class=\"selected\"" : "") . "><a href=\"" . $extforumurl."\" target=\"_blank\">".$lang_functions['text_forums']."</a></li>");
print ("<li" . ($selected == "torrents" ? " class=\"selected\"" : "") . "><a href=\"torrents.php\">".$lang_functions['text_torrents']."</a></li>");
if ($enablespecial == 'yes')
if ($enablespecial == 'yes' && get_user_class() >= get_setting('authority.view_special_torrent'))
print ("<li" . ($selected == "special" ? " class=\"selected\"" : "") . "><a href=\"special.php\">".$lang_functions['text_special']."</a></li>");
if ($enableoffer == 'yes')
print ("<li" . ($selected == "offers" ? " class=\"selected\"" : "") . "><a href=\"offers.php\">".$lang_functions['text_offers']."</a></li>");
@@ -5105,11 +5141,11 @@ function strip_all_tags($text)
//替换掉无参数标签
$bbTags = [
'[*]', '[b]', '[/b]', '[i]', '[/i]', '[u]', '[/u]', '[pre]', '[/pre]', '[quote]', '[/quote]',
'[/color]', '[/font]', '[/size]', '[/url]'
'[/color]', '[/font]', '[/size]', '[/url]', '[/youtube]',
];
$text = str_replace($bbTags, '', $text);
//替换掉有参数标签
$pattern = '/\[url=.*\]|\[color=.*\]|\[font=.*\]|\[size=.*\]/isU';
$pattern = '/\[url=.*\]|\[color=.*\]|\[font=.*\]|\[size=.*\]|\[youtube.*\]/isU';
$text = preg_replace($pattern, "", $text);
//去掉表情
static $emoji = null;
@@ -5365,7 +5401,7 @@ function build_medal_image(\Illuminate\Support\Collection $medals, $maxHeight =
if ($medal->pivot->status == \App\Models\UserMedal::STATUS_WEARING) {
$checked = ' checked';
}
$html .= sprintf('<label>%s<input type="checkbox" name="medal_wearing_status" value="%s"%s></label>', '佩戴', $medal->id, $checked);
$html .= sprintf('<label>%s<input type="checkbox" name="medal_wearing_status" value="%s"%s></label>', nexus_trans('medal.action_wearing'), $medal->pivot->id, $checked);
}
$html .= '</div>';
$medalImages[] = $html;

View File

@@ -320,6 +320,8 @@ $lang_functions = array
'text_technical_info_help_text' => 'MediaInfo 来自软件 <b><a href="https://mediaarea.net/en/MediaInfo" target=\'_blank\'>MediaInfo</a></b>,用该软件打开文件,点击菜单视图(View)->文件(Text),在框中右键->全选,再右键->复制,粘贴到这里来。',
'text_management_system' => '管理系统',
'text_seed_points' => '做种积分',
'spoiler_expand_collapse' => '点击展开/收缩',
'spoiler_default_title' => '折叠内容',
);
?>

View File

@@ -129,6 +129,10 @@ $lang_tags = array
'text_ninety_eight_image_syntax' => " [98img=[auto|number]]图片文件[/98img]",
'text_ninety_eight_image_example' => "[98img=150]uploadfile/2008/10/30/2362924185.png[/98img]",
'text_ninety_eight_image_remarks' => "CC98是浙江大学的一个论坛",
'text_spoiler' => '折叠',
'text_spoiler_description' => '在页面插入可展开/收缩的内容',
'text_spoiler_syntax' => '[spoiler=标题]这是被折叠的内容[/spoiler]',
'text_spoiler_example' => '[spoiler=英雄最后的结局怎么样了?]英雄最后死掉了![/spoiler]',
);
?>

View File

@@ -321,6 +321,8 @@ $lang_functions = array
'text_technical_info_help_text' => 'MediaInfo 來自軟件 <b><a href="https://mediaarea.net/en/MediaInfo" target=\'_blank\'>MediaInfo</a></b>,用該軟件打開文件,點擊菜單視圖(View)->文件(Text),在框中右鍵->全選,再右鍵->復制,粘貼到這裏來。',
'text_management_system' => '管理系統',
'text_seed_points' => '做種積分',
'spoiler_expand_collapse' => '點擊展開/收縮',
'spoiler_default_title' => '折疊內容',
);
?>

View File

@@ -129,6 +129,10 @@ $lang_tags = array
'text_ninety_eight_image_syntax' => " [98img=[auto|number]]圖片文件[/98img]",
'text_ninety_eight_image_example' => "[98img=150]uploadfile/2008/10/30/2362924185.png[/98img]",
'text_ninety_eight_image_remarks' => "CC98是浙江大學的一個論壇",
'text_spoiler' => '折疊',
'text_spoiler_description' => '在頁面插入可展開/收縮的內容',
'text_spoiler_syntax' => '[spoiler=標題]這是被折疊的內容[/spoiler]',
'text_spoiler_example' => '[spoiler=英雄最後的結局怎麽樣了?]英雄最後死掉了![/spoiler]',
);

View File

@@ -322,6 +322,8 @@ $lang_functions = array
'text_technical_info_help_text' => 'MediaInfo comes from software <b><a href="https://mediaarea.net/en/MediaInfo" target=\'_blank\'>MediaInfo</a></b>open file, click the view menu > text > right click in the box > select all > copy > past into this box.',
'text_management_system' => 'Management system',
'text_seed_points' => 'Seed points',
'spoiler_expand_collapse' => 'Click to expand/collapse',
'spoiler_default_title' => 'Collapse content',
);
?>

View File

@@ -129,6 +129,10 @@ $lang_tags = array
'text_ninety_eight_image_syntax' => " [98img=[auto|number]]image file[/98img]",
'text_ninety_eight_image_example' => "[98img=150]uploadfile/2008/10/30/2362924185.png[/98img]",
'text_ninety_eight_image_remarks' => "CC98 is a forum at Zhejiang University",
'text_spoiler' => 'Spoiler',
'text_spoiler_description' => 'Insert expandable/collapsible content on the page',
'text_spoiler_syntax' => '[spoiler=title]This is the folded content[/spoiler]',
'text_spoiler_example' => '[spoiler=What happened to the final ending of the hero?]The hero died last![/spoiler]',
);
?>

View File

@@ -217,33 +217,39 @@ final class Nexus
$this->platform = (string)$this->retrieveFromServer(['HTTP_PLATFORM', 'Platform', 'platform'], true);
}
public static function js(string $js, string $position, bool $isFile)
public static function js(string $js, string $position, bool $isFile, $key = null)
{
if ($isFile) {
$append = sprintf('<script type="text/javascript" src="%s"></script>', $js);
} else {
$append = sprintf('<script type="text/javascript">%s</script>', $js);
}
if ($position == 'header') {
self::$appendHeaders[] = $append;
} elseif ($position == 'footer') {
self::$appendFooters[] = $append;
} else {
throw new \InvalidArgumentException("Invalid position: $position");
}
self::appendJsCss($append, $position, $key);
}
public static function css(string $css, string $position, bool $isFile)
public static function css(string $css, string $position, bool $isFile, $key = null)
{
if ($isFile) {
$append = sprintf('<link rel="stylesheet" href="%s" type="text/css">', $css);
} else {
$append = sprintf('<style type="text/css">%s</style>', $css);
}
self::appendJsCss($append, $position, $key);
}
private static function appendJsCss($append, $position, $key = null)
{
if ($key === null) {
$key = md5($append);
}
if ($position == 'header') {
self::$appendHeaders[] = $append;
if (!isset(self::$appendHeaders[$key])) {
self::$appendHeaders[$key] = $append;
}
} elseif ($position == 'footer') {
self::$appendFooters[] = $append;
if (!isset(self::$appendFooters[$key])) {
self::$appendFooters[$key] = $append;
}
} else {
throw new \InvalidArgumentException("Invalid position: $position");
}

View File

@@ -480,3 +480,18 @@ img.hitandrun {
background: url(icons.gif) no-repeat -100px -171px;
margin-left: 0.5em;
}
.spoiler-title {
line-height: 40px;
color: #4d6c99;
cursor: pointer;
font-weight: 700;
background-color: rgba(77, 108, 153, 0.1);
display: inline-block;
padding: 0 10px;
}
.spoiler-content {
display: inline-block;
height: 0;
overflow: hidden;
transition: height 0.3s ease;
}

View File

@@ -252,6 +252,15 @@ insert_tag(
$lang_tags['text_ninety_eight_image_remarks']
);*/
insert_tag(
$lang_tags['text_spoiler'],
$lang_tags['text_spoiler_description'],
$lang_tags['text_spoiler_syntax'],
$lang_tags['text_spoiler_example'],
""
);
end_frame();
end_main_frame();
stdfoot();

View File

@@ -0,0 +1,8 @@
<?php
return [
'have_not_attendance_yet' => "Haven't attendance yet",
'target_date_can_no_be_retroactive' => 'Date:date can not be retroactive',
'already_attendance' => 'Already attendance',
'card_not_enough' => 'Attendance card not enough',
];

View File

@@ -1,6 +1,7 @@
<?php
return [
'action_wearing' => 'Wear',
'admin' => [
'list' => [
'page_title' => 'Medal list'

View File

@@ -0,0 +1,8 @@
<?php
return [
'have_not_attendance_yet' => '还没有签过到',
'target_date_can_no_be_retroactive' => '日期::date 无法补签',
'already_attendance' => '已经签到',
'card_not_enough' => '补签卡不足',
];

View File

@@ -1,6 +1,7 @@
<?php
return [
'action_wearing' => '佩戴',
'admin' => [
'list' => [
'page_title' => '勋章列表'

View File

@@ -0,0 +1,9 @@
<?php
return [
'have_not_attendance_yet' => '還沒有簽過到',
'target_date_can_no_be_retroactive' => '日期::date 無法補簽',
'already_attendance' => '已經簽到',
'card_not_enough' => '補簽卡不足',
];

View File

@@ -1,6 +1,7 @@
<?php
return [
'action_wearing' => '佩戴',
'admin' => [
'list' => [
'page_title' => '勛章列表'