mirror of
https://github.com/kuaifan/dootask.git
synced 2026-09-11 14:38:41 +00:00
feat(system): 支持自定义登录页品牌
This commit is contained in:
parent
ac43f630d3
commit
f43977f07e
@ -45,7 +45,7 @@ class SystemController extends AbstractController
|
||||
* @apiParam {String} type
|
||||
* - get: 获取(默认)
|
||||
* - all: 获取所有(需要管理员权限)
|
||||
* - save: 保存设置(参数:['reg', 'reg_identity', 'reg_invite', 'temp_account_alias', 'login_code', 'password_policy', 'project_invite', 'chat_information', 'anon_message', 'convert_video', 'compress_video', 'e2e_message', 'auto_archived', 'archived_day', 'task_visible', 'task_default_time', 'task_user_limit', 'all_group_mute', 'all_group_autoin', 'user_private_chat_mute', 'user_group_chat_mute', 'system_alias', 'system_welcome', 'image_compress', 'image_quality', 'image_save_local'])
|
||||
* - save: 保存设置(参数:['reg', 'reg_identity', 'reg_invite', 'temp_account_alias', 'login_code', 'password_policy', 'project_invite', 'chat_information', 'anon_message', 'convert_video', 'compress_video', 'e2e_message', 'auto_archived', 'archived_day', 'task_visible', 'task_default_time', 'task_user_limit', 'all_group_mute', 'all_group_autoin', 'user_private_chat_mute', 'user_group_chat_mute', 'system_alias', 'login_logo', 'system_welcome', 'image_compress', 'image_quality', 'image_save_local'])
|
||||
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
@ -89,6 +89,7 @@ class SystemController extends AbstractController
|
||||
'user_private_chat_mute',
|
||||
'user_group_chat_mute',
|
||||
'system_alias',
|
||||
'login_logo',
|
||||
'system_welcome',
|
||||
'image_compress',
|
||||
'image_quality',
|
||||
@ -114,6 +115,10 @@ class SystemController extends AbstractController
|
||||
if ($all['system_alias'] == config('app.name')) {
|
||||
$all['system_alias'] = '';
|
||||
}
|
||||
if (isset($all['login_logo'])) {
|
||||
$loginLogo = $all['login_logo'];
|
||||
$all['login_logo'] = $loginLogo ? Base::unFillUrl(is_array($loginLogo) ? $loginLogo[0]['path'] : $loginLogo) : '';
|
||||
}
|
||||
if ($all['system_welcome'] == '欢迎您,{username}') {
|
||||
$all['system_welcome'] = '';
|
||||
}
|
||||
@ -130,6 +135,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
//
|
||||
$setting['system_alias'] = ($setting['system_alias'] ?? '') ?: config('app.name');
|
||||
$setting['login_logo'] = Base::fillUrl($setting['login_logo'] ?? '');
|
||||
$setting['reg'] = $setting['reg'] ?: 'open';
|
||||
$setting['reg_identity'] = $setting['reg_identity'] ?: 'normal';
|
||||
$setting['temp_account_alias'] = $setting['temp_account_alias'] ?: '';
|
||||
|
||||
@ -75,6 +75,7 @@ class IndexController extends InvokeController
|
||||
}
|
||||
return response()->view('main', [
|
||||
'system_alias' => Base::settingFind('system', 'system_alias', 'WebPage'),
|
||||
'login_logo' => Base::fillUrl(Base::settingFind('system', 'login_logo')),
|
||||
'version' => Base::getVersion(),
|
||||
'style' => $style,
|
||||
'script' => $script,
|
||||
|
||||
1
electron/build.js
vendored
1
electron/build.js
vendored
@ -347,6 +347,7 @@ async function startBuild(data) {
|
||||
// system info
|
||||
const systemInfo = {
|
||||
title: data.name,
|
||||
loginLogo: "",
|
||||
debug: "no",
|
||||
version: config.version,
|
||||
origin: "./",
|
||||
|
||||
@ -1778,7 +1778,7 @@ WiFi签到延迟时长为±1分钟。
|
||||
最多添加5个时间范围
|
||||
|
||||
系统别名
|
||||
用于网页默认标题、邮件发送等
|
||||
用于网页标题、邮件发送,以及 Web 端和客户端登录页的欢迎语。
|
||||
|
||||
打包权限
|
||||
允许所有人
|
||||
@ -2739,3 +2739,5 @@ WebDAV 路径冲突
|
||||
上传与媒体处理
|
||||
至少保留一项
|
||||
确定要删除该优先级吗?
|
||||
登录页 Logo
|
||||
用于 Web 端和客户端登录页,未设置时使用默认 Logo。
|
||||
|
||||
@ -25380,16 +25380,16 @@
|
||||
"ru": "Системный псевдоним"
|
||||
},
|
||||
{
|
||||
"key": "用于网页默认标题、邮件发送等",
|
||||
"key": "用于网页标题、邮件发送,以及 Web 端和客户端登录页的欢迎语。",
|
||||
"zh": "",
|
||||
"zh-CHT": "用於網頁默認標題、郵件發送等",
|
||||
"en": "Used for web default titles, email sending, etc.",
|
||||
"ko": "웹 기본 제목, 이메일 전송 등에 사용",
|
||||
"ja": "ウェブのデフォルトタイトル、メール送信などに使用されます",
|
||||
"de": "Wird für Web-Standardtitel, E-Mail-Versand usw. verwendet",
|
||||
"fr": "Utilisé pour les titres par défaut des pages Web, l'envoi d'e-mails, etc.",
|
||||
"id": "Digunakan untuk judul default web, pengiriman email, dll.",
|
||||
"ru": "Используется для веб-страниц по умолчанию, отправки электронной почты и т. д."
|
||||
"zh-CHT": "用於網頁標題、郵件發送,以及 Web 端和客戶端登入頁的歡迎語。",
|
||||
"en": "Used for webpage titles, email delivery, and the welcome message on Web and client login pages.",
|
||||
"ko": "웹 페이지 제목, 이메일 발송, Web 및 클라이언트 로그인 페이지의 환영 문구에 사용됩니다.",
|
||||
"ja": "Webページのタイトル、メール送信、Web版およびクライアント版のログインページのウェルカムメッセージに使用されます。",
|
||||
"de": "Wird für Webseitentitel, den E-Mail-Versand und die Begrüßung auf den Anmeldeseiten der Web- und Client-Version verwendet.",
|
||||
"fr": "Utilisé pour les titres des pages Web, l'envoi d'e-mails et le message de bienvenue des pages de connexion Web et client.",
|
||||
"id": "Digunakan untuk judul halaman web, pengiriman email, dan pesan sambutan pada halaman login Web dan klien.",
|
||||
"ru": "Используется для заголовков веб-страниц, отправки электронной почты и приветствия на страницах входа веб-версии и клиента."
|
||||
},
|
||||
{
|
||||
"key": "打包下载【(%T1)】文件夹",
|
||||
@ -39586,5 +39586,29 @@
|
||||
"fr": "Afficher dans le dossier",
|
||||
"id": "Tampilkan di Folder",
|
||||
"ru": "Показать в папке"
|
||||
},
|
||||
{
|
||||
"key": "登录页 Logo",
|
||||
"zh": "",
|
||||
"zh-CHT": "登錄頁 Logo",
|
||||
"en": "Login Page Logo",
|
||||
"ko": "로그인 페이지 로고",
|
||||
"ja": "ログインページのロゴ",
|
||||
"de": "Logo der Anmeldeseite",
|
||||
"fr": "Logo de la page de connexion",
|
||||
"id": "Logo Halaman Masuk",
|
||||
"ru": "Логотип страницы входа"
|
||||
},
|
||||
{
|
||||
"key": "用于 Web 端和客户端登录页,未设置时使用默认 Logo。",
|
||||
"zh": "",
|
||||
"zh-CHT": "用於 Web 端和客戶端登入頁,未設定時使用預設 Logo。",
|
||||
"en": "Used on Web and client login pages. The default logo is used when not configured.",
|
||||
"ko": "Web 및 클라이언트 로그인 페이지에 사용되며, 설정하지 않으면 기본 로고가 사용됩니다.",
|
||||
"ja": "Web版およびクライアント版のログインページで使用されます。未設定の場合はデフォルトのロゴが使用されます。",
|
||||
"de": "Wird auf den Anmeldeseiten der Web- und Client-Version verwendet. Ohne Konfiguration wird das Standardlogo verwendet.",
|
||||
"fr": "Utilisé sur les pages de connexion Web et client. Le logo par défaut est utilisé si aucun logo n'est configuré.",
|
||||
"id": "Digunakan pada halaman login Web dan klien. Logo default digunakan jika tidak dikonfigurasi.",
|
||||
"ru": "Используется на страницах входа веб-версии и клиента. Если не настроено, используется логотип по умолчанию."
|
||||
}
|
||||
]
|
||||
|
||||
2
public/language/web/de.js
vendored
2
public/language/web/de.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/en.js
vendored
2
public/language/web/en.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/fr.js
vendored
2
public/language/web/fr.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/id.js
vendored
2
public/language/web/id.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ja.js
vendored
2
public/language/web/ja.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/key.js
vendored
2
public/language/web/key.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ko.js
vendored
2
public/language/web/ko.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/ru.js
vendored
2
public/language/web/ru.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/zh-CHT.js
vendored
2
public/language/web/zh-CHT.js
vendored
File diff suppressed because one or more lines are too long
2
public/language/web/zh.js
vendored
2
public/language/web/zh.js
vendored
File diff suppressed because one or more lines are too long
@ -26,7 +26,7 @@ negative:
|
||||
- SYSTEM_SETTING=disabled 时所有系统设置都不能改(演示环境常用)
|
||||
- 自动归档天数限制为 1-100 天,超出会报错
|
||||
- 邀请码留空会自动生成随机码,不能完全关闭"凭码注册"模式
|
||||
last_verified: v1.8.89
|
||||
last_verified: v1.9.18
|
||||
---
|
||||
|
||||
# 通用设置
|
||||
@ -66,7 +66,8 @@ last_verified: v1.8.89
|
||||
- `file_upload_limit` — 单文件上传大小(MB)
|
||||
|
||||
**外观**
|
||||
- `system_alias` / `system_welcome` — 系统名称别名与欢迎语
|
||||
- `system_alias` / `system_welcome` — 系统名称别名与欢迎语;系统别名同时显示在 Web、桌面端和移动端登录页的 `Welcome` 标题中
|
||||
- `login_logo` — 登录页 Logo;支持上传、预览和删除,删除后恢复内置 DooTask Logo
|
||||
- 系统别名与部署的默认应用名称相同时,服务端使用空值存储以表示“沿用默认名称”,但保存响应和后续读取仍显示实际默认名称
|
||||
|
||||
## 操作步骤
|
||||
|
||||
@ -20,7 +20,7 @@ negative:
|
||||
- 账号被停用(disable_at 非空)会提示「帐号已停用」,需联系管理员
|
||||
- 开启「注册需邮箱验证」时,未验证邮箱的账号无法登录,必须先完成验证([[user-account.email-verify.howto]])
|
||||
- 多次失败后系统会强制要求填验证码([[user-account.login-codeimg.howto]])
|
||||
last_verified: v1.7.90
|
||||
last_verified: v1.9.18
|
||||
---
|
||||
|
||||
# 登录账号
|
||||
@ -28,6 +28,7 @@ last_verified: v1.7.90
|
||||
## 入口
|
||||
- 登录页:`/login`
|
||||
- 客户端启动时自动跳转
|
||||
- Web、桌面端和移动端登录页会显示管理员配置的登录 Logo 和系统别名;未配置时显示内置 DooTask 品牌
|
||||
|
||||
## 支持的登录方式
|
||||
DooTask 同时支持以下登录方式(在登录页可切换):
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div class="page-login">
|
||||
<PageTitle :title="$L('登录')"/>
|
||||
<div class="login-body">
|
||||
<div class="login-logo no-dark-content"></div>
|
||||
<div class="login-logo no-dark-content" :style="loginLogo ? {'background-image': 'url(' + loginLogo + ')'} : null"></div>
|
||||
<div class="login-box">
|
||||
<div class="login-mode-switch">
|
||||
<div class="login-mode-switch-box">
|
||||
@ -245,24 +245,31 @@ export default {
|
||||
|
||||
'themeConf',
|
||||
'themeList',
|
||||
'systemConfig',
|
||||
]),
|
||||
|
||||
currentLanguage() {
|
||||
return languageList[languageName] || 'Language'
|
||||
},
|
||||
|
||||
systemAlias() {
|
||||
return this.systemConfig.system_alias || window.systemInfo.title || "DooTask"
|
||||
},
|
||||
|
||||
loginLogo() {
|
||||
return this.systemConfig.login_logo || window.systemInfo.loginLogo || ''
|
||||
},
|
||||
|
||||
welcomeTitle() {
|
||||
if (this.loginMode == 'qrcode') {
|
||||
return this.$L("扫码登录")
|
||||
}
|
||||
const title = window.systemInfo.title || "DooTask";
|
||||
return "Welcome " + title
|
||||
return "Welcome " + this.systemAlias
|
||||
},
|
||||
|
||||
subTitle() {
|
||||
const title = window.systemInfo.title || "DooTask";
|
||||
if (this.loginMode == 'qrcode') {
|
||||
return this.$L('请使用(*)移动端扫描二维码。', title)
|
||||
return this.$L('请使用(*)移动端扫描二维码。', this.systemAlias)
|
||||
}
|
||||
if (this.loginType=='reg') {
|
||||
return this.$L('输入您的信息以创建帐户。')
|
||||
|
||||
@ -285,7 +285,16 @@
|
||||
<div style="width: 220px;">
|
||||
<Input v-model="formDatum.system_alias"/>
|
||||
</div>
|
||||
<div class="form-tip">{{$L('用于网页默认标题、邮件发送等')}}</div>
|
||||
<div class="form-tip">{{$L('用于网页标题、邮件发送,以及 Web 端和客户端登录页的欢迎语。')}}</div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('登录页 Logo')" prop="login_logo">
|
||||
<ImgUpload
|
||||
v-model="formDatum.login_logo"
|
||||
:num="1"
|
||||
:width="512"
|
||||
:height="512"
|
||||
whcut="percentage"/>
|
||||
<div class="form-tip">{{$L('用于 Web 端和客户端登录页,未设置时使用默认 Logo。')}}</div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('欢迎词')" prop="system_welcome">
|
||||
<div style="width: 220px;">
|
||||
@ -359,9 +368,10 @@ import UserSelect from "../../../../components/UserSelect.vue";
|
||||
import SystemColumnTemplate from "./SystemColumnTemplate.vue";
|
||||
import SystemFileSetting from "./SystemFileSetting.vue";
|
||||
import SystemTaskPriority from "./SystemTaskPriority.vue";
|
||||
import ImgUpload from "../../../../components/ImgUpload.vue";
|
||||
|
||||
const SCOPE_FIELDS = {
|
||||
general: ['system_alias', 'system_welcome'],
|
||||
general: ['system_alias', 'login_logo', 'system_welcome'],
|
||||
account: ['reg', 'reg_identity', 'reg_invite', 'temp_account_alias', 'login_code', 'password_policy'],
|
||||
project: ['project_invite', 'project_add_permission', 'project_add_userids', 'department_owner_project_view'],
|
||||
task: ['auto_archived', 'archived_day', 'task_visible', 'task_default_time', 'task_user_limit', 'unclaimed_task_reminder', 'unclaimed_task_reminder_time', 'task_ai_auto_analyze'],
|
||||
@ -372,7 +382,7 @@ const SCOPE_FIELDS = {
|
||||
export default {
|
||||
name: 'SystemSetting',
|
||||
|
||||
components: {SystemTaskPriority, SystemFileSetting, SystemColumnTemplate, UserSelect},
|
||||
components: {ImgUpload, SystemTaskPriority, SystemFileSetting, SystemColumnTemplate, UserSelect},
|
||||
|
||||
props: {
|
||||
scope: {
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
};
|
||||
window.systemInfo = {
|
||||
title: "{{$system_alias}}",
|
||||
loginLogo: "{{$login_logo}}",
|
||||
debug: "{{config('app.debug') ? 'yes' : 'no'}}",
|
||||
version: "{{ $version }}",
|
||||
origin: window.location.origin + "/",
|
||||
|
||||
39
tests/Feature/SystemBrandingTest.php
Normal file
39
tests/Feature/SystemBrandingTest.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Module\Base;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class SystemBrandingTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function test_public_system_setting_exposes_login_branding(): void
|
||||
{
|
||||
Base::setting('system', [
|
||||
'system_alias' => 'Example Team',
|
||||
'login_logo' => 'uploads/user/picture/1/202609/example.png',
|
||||
], true);
|
||||
|
||||
$response = $this->getJson('/api/system/setting')
|
||||
->assertOk()
|
||||
->assertJsonPath('ret', 1)
|
||||
->assertJsonPath('data.system_alias', 'Example Team');
|
||||
|
||||
$this->assertStringEndsWith(
|
||||
'/uploads/user/picture/1/202609/example.png',
|
||||
$response->json('data.login_logo')
|
||||
);
|
||||
|
||||
$page = $this->get('/login')
|
||||
->assertOk()
|
||||
->assertSee('Example Team', false);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'/uploads/user/picture/1/202609/example.png',
|
||||
str_replace('\/', '/', $page->getContent())
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user