From 9b14120055ce3bae3d32b8511beb8a0824cc1a3e Mon Sep 17 00:00:00 2001 From: kuaifan Date: Mon, 13 Jul 2026 23:54:23 +0000 Subject: [PATCH] =?UTF-8?q?fix(application):=20=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E5=8F=AF=E8=A7=81=E8=8C=83=E5=9B=B4=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=20app=20=E9=A1=B6=E5=B1=82=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=85=A8=E5=91=98=E5=8F=AF=E8=A7=81=E5=A4=B1=E6=95=88=E4=B8=8E?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=9B=9E=E5=A1=AB=E9=87=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 前后端对 visible_to 存放层级约定不一致导致两个 bug: - 新增应用设为全员可见,普通成员仍看不到(前端存在 menu 级,后端只认 app 级,落库恒回落为 admin) - 再次编辑时可见范围被重置为"仅管理员"(响应无条件剥离 visible_to,回填丢失) 统一以 app 顶层为唯一权威来源: - 前端保存时提到 app 顶层,回填时从 app 顶层读回(数组转下拉框字符串) - 后端响应新增 keepVisible,管理员保存/读取场景保留 visible_to,普通成员仍剥离 同步 ai-kb application/menu-admin last_verified。 --- app/Http/Controllers/Api/SystemController.php | 4 ++-- app/Models/Setting.php | 11 ++++++++--- resources/ai-kb/zh/howto/application/menu-admin.md | 2 +- resources/assets/js/pages/manage/application.vue | 8 +++++++- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Api/SystemController.php b/app/Http/Controllers/Api/SystemController.php index 804bc36d5..b25fc2623 100755 --- a/app/Http/Controllers/Api/SystemController.php +++ b/app/Http/Controllers/Api/SystemController.php @@ -778,14 +778,14 @@ class SystemController extends AbstractController } $apps = Setting::normalizeCustomMicroApps($list); $setting = Base::setting('microapp_menu', $apps); - $setting = Setting::formatCustomMicroAppsForResponse($setting); + $setting = Setting::formatCustomMicroAppsForResponse($setting, true); } else { $setting = Base::setting('microapp_menu'); if (!is_array($setting)) { $setting = []; } $setting = Setting::filterCustomMicroAppsForUser($setting, $user); - $setting = Setting::formatCustomMicroAppsForResponse($setting); + $setting = Setting::formatCustomMicroAppsForResponse($setting, $user && $user->isAdmin()); } return Base::retSuccess($type == 'save' ? '保存成功' : 'success', $setting); } diff --git a/app/Models/Setting.php b/app/Models/Setting.php index b529e5fc2..c8866efc6 100644 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -358,12 +358,17 @@ class Setting extends AbstractModel /** * 将存储结构转换成 appstore 接口同款格式 * @param array $apps + * @param bool $keepVisible 是否保留可见范围(仅管理员编辑场景需要,用于回填) * @return array */ - public static function formatCustomMicroAppsForResponse(array $apps) + public static function formatCustomMicroAppsForResponse(array $apps, bool $keepVisible = false) { - return array_values(array_map(function ($app) { - unset($app['visible_to']); + return array_values(array_map(function ($app) use ($keepVisible) { + if ($keepVisible) { + $app['visible_to'] = self::normalizeCustomMicroVisible($app['visible_to'] ?? ['admin']); + } else { + unset($app['visible_to']); + } if (!empty($app['menu_items']) && is_array($app['menu_items'])) { $app['menu_items'] = array_values(array_map(function ($menu) { $menu['keep_alive'] = isset($menu['keep_alive']) ? (bool)$menu['keep_alive'] : true; diff --git a/resources/ai-kb/zh/howto/application/menu-admin.md b/resources/ai-kb/zh/howto/application/menu-admin.md index 0fcd89450..ae950b20d 100644 --- a/resources/ai-kb/zh/howto/application/menu-admin.md +++ b/resources/ai-kb/zh/howto/application/menu-admin.md @@ -19,7 +19,7 @@ negative: - 仅管理员可见入口和保存接口 - 自定义菜单只是注册一个 URL/iframe 入口,DooTask 不托管业务页面 - 配置项里没有"权限继承项目角色"的开关 -last_verified: v1.7.90 +last_verified: v1.8.64 --- # 管理员自定义全员应用菜单 diff --git a/resources/assets/js/pages/manage/application.vue b/resources/assets/js/pages/manage/application.vue index a89c3e6b2..b86a8b297 100644 --- a/resources/assets/js/pages/manage/application.vue +++ b/resources/assets/js/pages/manage/application.vue @@ -659,9 +659,14 @@ export default { } return list.map(app => { const draft = createCustomMicroMenu(); - return Object.assign({}, draft, app, { + const merged = Object.assign({}, draft, app, { menu: Object.assign({}, draft.menu, $A.isArray(app.menu_items) && app.menu_items.length > 0 ? app.menu_items[0] : {}), }); + // 可见范围以 app 顶层为准,后端存数组,下拉框用字符串(当前仅 admin/all 两选项) + merged.menu.visible_to = $A.isArray(app.visible_to) + ? (app.visible_to.includes('all') ? 'all' : 'admin') + : (app.visible_to || 'admin'); + return merged; }); }, pickCustomMenuLabel(label, fallback = '') { @@ -739,6 +744,7 @@ export default { id, name: (item.name || '').trim(), version: item.version || 'custom', + visible_to: item.menu.visible_to || 'admin', menu_items: [Object.assign({}, item.menu, { url, label })], }; },