OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)

This commit is contained in:
wangruiguo
2026-09-03 18:49:20 +08:00
commit d647428529
3501 changed files with 1988906 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
@php
$lastClient = '';
@endphp
<ul id="{{ $prefix }}-projectSelectorlist-group-{{ $parent }}" class="level-{{ $level }} projectGroup">
@foreach($projects as $project)
@php
$parentState = session("usersettings.submenuToggle.".$prefix.'-projectSelectorlist-group-'.$project['clientId'], 'closed');
@endphp
@if(
!session()->exists("usersettings.projectSelectFilter.client")
|| session("usersettings.projectSelectFilter.client") == $project["clientId"]
|| session("usersettings.projectSelectFilter.client") == 0
|| session("usersettings.projectSelectFilter.client") == ""
)
@if ($lastClient != $project['clientName'])
@php
$lastClient = $project['clientName']
@endphp
@if(!$loop->first)
</ul>
@endif
<li class='projectLineItem clientIdHead-{{$project['clientId'] }}'>
<a href="javascript:void(0);"
class="toggler {{ $parentState }}"
id="{{ $prefix }}-toggler-{{ $project["clientId"] }}"
onclick="leantime.menuController.toggleProjectDropDownList('{{ $project["clientId"] }}', '', '{{ $prefix }}')">
@if($parentState == 'closed')
<i class="fa fa-angle-right"></i>
@else
<i class="fa fa-angle-down"></i>
@endif
</a>
<a href="javascript:void(0)">
{{ $project['clientName'] }}
</a>
<ul id="{{ $prefix }}-projectSelectorlist-group-{{ $project['clientId'] }}" class="level-1 projectGroup {{ $parentState }}">
@endif
<li class="projectLineItem hasSubtitle {{ session("currentProject") == $project['id'] ? "active" : '' }}" >
@include('menu::partials.projectLink')
<div class="clear"></div>
</li>
@endif
@endforeach
</ul>

View File

@@ -0,0 +1,5 @@
<li class="fixedMenuPoint {{ $module == $settingsLink['module'] && $action == $settingsLink['action'] ? 'active' : '' }}">
<a href="@if(isset($settingsLink['url'])) {{ $settingsLink['url'] }} @else {{ BASE_URL }}/{{ $settingsLink['module'] }}/{{ $settingsLink['action'] }} @endif">
{!! __($settingsLink['label']) !!}
</a>
</li>

View File

@@ -0,0 +1,5 @@
<li class="title">
<a href="javascript:void(0);">
<strong>{!! __($menuItem['title']) !!}</strong>
</a>
</li>

View File

@@ -0,0 +1,25 @@
@if(!isset($menuItem['role']) || $login::userIsAtLeast($menuItem['role'] ?? 'editor'))
<li
@if(
$module == $menuItem['module']
&& (!isset($menuItem['active']) || in_array($action, $menuItem['active']))
)
class='active'
@endif
>
<a href="{{ BASE_URL . $menuItem['href'] }}"
data-tippy-content="{{ strip_tags(__($menuItem['tooltip'])) }}"
data-tippy-placement="right"
preload="mouseover"
@if(isset($menuItem['attributes']))
@foreach($menuItem['attributes'] as $key => $value)
{{ $key }}="{{ $value }}"
@endforeach
@endif
>
{!! $menuItem['title'] !!}
</a>
</li>
@endif

View File

@@ -0,0 +1 @@
<li class="separator"></li>

View File

@@ -0,0 +1,27 @@
@if(!isset($menuItem['role']) || $login::userIsAtLeast($menuItem['role'] ?? 'editor'))
<li class="submenuToggle">
<a href="javascript:void(0);"
@if ( $menuItem['visual'] !== 'always' )
onclick="leantime.menuController.toggleSubmenu('{{ $menuItem['id'] }}')"
@endif
>
<i class="submenuCaret fa fa-angle-{{ $menuItem['visual'] == 'closed' ? 'right' : 'down' }}"
id="submenu-icon-{{ $menuItem['id'] }}"></i>
<strong>{!! __($menuItem['title']) !!}</strong>
</a>
</li>
<ul id="submenu-{{ $menuItem['id'] }}" class="submenu {{ $menuItem['visual'] == 'closed' ? 'closed' : 'open' }}">
@foreach ($menuItem['submenu'] as $subkey => $submenuItem)
@switch ($submenuItem['type'])
@case('header')
@include("menu::partials.leftnav.header", ["menuItem" => $submenuItem, "module" => $module, "action" => $action])
@break
@case('item')
@include("menu::partials.leftnav.item", ["menuItem" => $submenuItem, "module" => $module, "action" => $action])
@endswitch
@endforeach
</ul>
@endif

View File

@@ -0,0 +1,19 @@
<ul class="level-0 noGroup">
@foreach($projects as $project)
@if(
!session()->exists("usersettings.projectSelectFilter.client")
|| session("usersettings.projectSelectFilter.client") == $project["clientId"]
|| session("usersettings.projectSelectFilter.client") == 0
|| session("usersettings.projectSelectFilter.client") == ""
)
<li class="projectLineItem hasSubtitle {{ session("currentProject") ?? 0 == $project['id'] ? "active" : '' }}" >
@include('menu::partials.projectLink')
<div class="clear"></div>
</li>
@endif
@endforeach
</ul>

View File

@@ -0,0 +1,46 @@
@php
$groupState = session("usersettings.submenuToggle.".$prefix.'-projectSelectorlist-group-'.$parent, 'closed');
@endphp
<ul id="{{ $prefix }}-projectSelectorlist-group-{{ $parent }}" class="level-{{ $level }} projectGroup {{ $groupState }}">
@foreach($projects as $project)
@if(
!session()->exists("usersettings.projectSelectFilter.client")
|| session("usersettings.projectSelectFilter.client") == $project["clientId"]
|| session("usersettings.projectSelectFilter.client") == 0
|| session("usersettings.projectSelectFilter.client") == ""
|| $project["clientId"] == ''
)
<li class="projectLineItem hasSubtitle {{ session("currentProject") == $project['id'] ? "active" : '' }}" >
@php
$parentState = session("usersettings.submenuToggle.".$prefix.'-projectSelectorlist-group-'.$project['id'], 'closed');
@endphp
@if((empty($project['children']) || count($project['children']) ==0))
<span class="toggler"></span>
@endif
@if(!empty($project['children']) && count($project['children']) >0)
<a href="javascript:void(0);" class="toggler {{ $parentState }}" id="{{ $prefix }}-toggler-{{ $project["id"] }}" onclick="leantime.menuController.toggleProjectDropDownList('{{ $project["id"] }}', '', '{{ $prefix }}')">
@if($parentState == 'closed')
<i class="fa fa-angle-right"></i>
@else
<i class="fa fa-angle-down"></i>
@endif
</a>
@endif
@include('menu::partials.projectLink')
<div class="clear"></div>
{{-- Depth cap: the hierarchy is cycle-guarded server-side, but a runaway
tree (e.g. mutated by a plugin filter) must never recurse unbounded --}}
@if(!empty($project['children']) && count($project['children']) >0 && $level < 20)
@include('menu::partials.projectGroup', ['projects' => $project['children'], 'parent' => $project['id'], 'level'=> $level+1, 'prefix' => $prefix, "currentProject"=>$currentProject])
@endif
</li>
@endif
@endforeach
</ul>

View File

@@ -0,0 +1,21 @@
<a href='{{ BASE_URL }}/projects/changeCurrentProject/{{ $project["id"] }}'
@if(strlen($project["name"]) > 25)
data-tippy-content='{{ $project["name"] }}'
@endif >
<span class='projectAvatar'>
@if(isset($projectTypeAvatars[$project["type"]]) && $projectTypeAvatars[$project["type"]] != "avatar")
<span class="{{ $projectTypeAvatars[$project["type"]] }}"></span>
@else
<img src='{{ BASE_URL }}/api/projects?projectAvatar={{ $project["id"] }}&v={{ format($project['modified'])->timestamp() }}' />
@endif
</span>
<span class='projectName'>
@if($project["clientName"] != '')
<small>{{ $project["clientName"] }}</small><br />
@else
<small>{{ __('projectType.'.$project["type"] ?? 'project') }}</small><br />
@endif
{{ $project["name"] }}
</span>
</a>

View File

@@ -0,0 +1,49 @@
<div class="projectListFilter">
<form
hx-target="#mainProjectSelector"
hx-swap="outerHTML"
hx-trigger="change">
<i class="fas fa-filter"></i>
<select data-placeholder="" title=""
hx-post="{{ BASE_URL }}/hx/menu/projectSelector/update-menu"
hx-target="#mainProjectSelector"
hx-swap="outerHTML"
hx-indicator=".htmx-indicator, .htmx-loaded-content"
name="client">
<option value="" data-placeholder="true">All Clients</option>
@foreach ($clients as $client)
@if($client['id'] > 0)
<option value='{{ $client['id'] }}'
@if (isset($projectSelectFilter['client']) && $projectSelectFilter['client'] == $client['id'])
selected='selected'
@endif
>{{ $client['name'] }}</option>
@endif
@endforeach
</select>
<i class="fa-solid fa-diagram-project"></i>
<select data-placeholder="" name="groupBy"
hx-post="{{ BASE_URL }}/hx/menu/projectSelector/update-menu"
hx-target="#mainProjectSelector"
hx-indicator=".htmx-indicator, .htmx-loaded-content"
hx-swap="outerHTML">
@foreach ($projectSelectGroupOptions as $key => $group)
<option value='{{ $key }}'
{{ $projectSelectFilter["groupBy"] == $key ? " selected='selected' " : "" }}
>{{ $group }}</option>
@endforeach
</select>
<input type="hidden" name="activeTab" value="" />
</form>
</div>
<div class="htmx-indicator tw-ml-m tw-mr-m tw-pt-l">
<x-global::loadingText type="project" count="5" includeHeadline="false"/>
</div>

View File

@@ -0,0 +1,126 @@
@props([
'redirect' => 'dashboard/show',
'currentProject'
])
<div class="dropdown-menu projectselector" id="mainProjectSelector">
@if ($menuType == 'project' || $menuType == 'default')
<div class="head">
<span class="sub">{{ __("menu.current_project") }}</span><br />
<span class="title">{{ session("currentProjectName") }}</span>
</div>
@else
<div class="projectSelectorFooter" style="border:none; border-bottom:1px solid var(--main-border-color)">
<ul class="selectorList projectList">
<li>
<a href="{{ BASE_URL }}/projects/showMy"><strong><i class="fa-solid fa-house-flag"></i> Open Project Hub</strong></a>
</li>
@if ($login::userIsAtLeast("manager"))
@dispatchEvent('beforeProjectCreateLink')
<li><a href="{{ $startSomethingUrl }}">
<span class="fancyLink">
{!! __('menu.create_something_new') !!}
</span>
</a>
</li>
@dispatchEvent('afterProjectCreateLink')
@endif
</ul>
</div>
@endif
<div class="tabbedwidget tab-primary projectSelectorTabs">
<ul class="tabs">
<li><a href="#myProjects">{{ __('menu.projectselector.my_projects') }}</a></li>
<li><a href="#favorites">{{ __('menu.projectselector.favorites') }}</a></li>
<li><a href="#recentProjects">{{ __('menu.projectselector.recent') }}</a></li>
<li><a href="#allProjects">{{ __('menu.projectselector.all_projects') }}</a></li>
</ul>
<div id="myProjects" class="scrollingTab">
@include('menu::partials.projectListFilter', ['clients' => $clients, 'projectSelectFilter' => $projectSelectFilter])
<ul class="selectorList projectList htmx-loaded-content">
@if($projectSelectFilter["groupBy"] == "client")
@include('menu::partials.clientGroup', ['projects' => $allAssignedProjects, 'parent' => 0, 'level'=> 0, "prefix" => "myClientProjects", "currentProject"=>$currentProject])
@elseif($projectSelectFilter["groupBy"] == "structure")
@include('menu::partials.projectGroup', ['projects' => $projectHierarchy, 'parent' => 0, 'level'=> 0, "prefix" => "myProjects", "currentProject"=>$currentProject])
@else
@include('menu::partials.noGroup', ['projects' => $allAssignedProjects, "currentProject"=>$currentProject])
@endif
</ul>
</div>
<div id="allProjects" class="scrollingTab">
@include('menu::partials.projectListFilter', ['clients' => $clients, 'projectSelectFilter' => $projectSelectFilter])
<ul class="selectorList projectList htmx-loaded-content">
@if($projectSelectFilter["groupBy"] == "client")
@include('menu::partials.clientGroup', ['projects' => $allAvailableProjects, 'parent' => 0, 'level'=> 0, "prefix" => "allClientProjects", "currentProject"=>$currentProject])
@elseif($projectSelectFilter["groupBy"] == "structure")
@include('menu::partials.projectGroup', ['projects' => $allAvailableProjectsHierarchy, 'parent' => 0, 'level'=> 0, "prefix" => "allProjects", "currentProject"=>$currentProject])
@else
@include('menu::partials.noGroup', ['projects' => $allAvailableProjects, "currentProject"=>$currentProject])
@endif
</ul>
</div>
<div id="recentProjects" class="scrollingTab">
<ul class="selectorList projectList">
@if(count($recentProjects) >= 1)
@include('menu::partials.noGroup', ['projects' => $recentProjects])
@else
<li class='nav-header'></li>
<li><span class='info'>
{{ __("menu.you_dont_have_projects") }}
</span>
</li>
@endif
</ul>
</div>
<div id="favorites" class="scrollingTab">
<ul class="selectorList projectList">
@if(count($favoriteProjects) >= 1)
@include('menu::partials.noGroup', ['projects' => $favoriteProjects])
@else
<li><span class='info'>
{{ __("text.you_have_not_favorited_any_projects") }}
</span>
</li>
@endif
</ul>
</div>
</div>
@if ($menuType == 'project' || $menuType == 'default')
<div class="projectSelectorFooter">
<ul class="selectorList projectList">
@if ($login::userIsAtLeast("manager"))
@dispatchEvent('beforeProjectCreateLink')
<li><a href="{{ $startSomethingUrl }}">
<span class="fancyLink">
{!! __('menu.create_something_new') !!}
</span>
</a>
</li>
@dispatchEvent('afterProjectCreateLink')
@endif
<li>
<a href="{{ BASE_URL }}/projects/showMy"><i class="fa-solid fa-circle-nodes"></i> Project Hub</a>
</li>
</ul>
</div>
@endif
</div>
<script>
jQuery(document).ready(function () {
leantime.menuController.initProjectSelector();
});
</script>