diff --git a/client-deployment/custom-config.env b/client-deployment/custom-config.env index 1c82d60..3486cdd 100644 --- a/client-deployment/custom-config.env +++ b/client-deployment/custom-config.env @@ -13,8 +13,8 @@ LJWX_ADMIN_VERSION=2.0.1 # 服务器IP地址 - 根据实际部署环境修改 SERVER_IP=192.168.1.83 # 各服务外部端口配置 -MYSQL_EXTERNAL_PORT=3306 -REDIS_EXTERNAL_PORT=6379 +MYSQL_EXTERNAL_PORT=23306 +REDIS_EXTERNAL_PORT=26379 LJWX_BOOT_EXTERNAL_PORT=9999 LJWX_BIGSCREEN_EXTERNAL_PORT=8001 LJWX_ADMIN_EXTERNAL_PORT=8088 diff --git a/ljwx-admin/src/components/business/CustomerSelector.vue b/ljwx-admin/src/components/business/CustomerSelector.vue new file mode 100644 index 0000000..644e769 --- /dev/null +++ b/ljwx-admin/src/components/business/CustomerSelector.vue @@ -0,0 +1,121 @@ + + + + + \ No newline at end of file diff --git a/ljwx-admin/src/components/common/CustomerSwitcher.vue b/ljwx-admin/src/components/common/CustomerSwitcher.vue index 27ca612..71825b3 100644 --- a/ljwx-admin/src/components/common/CustomerSwitcher.vue +++ b/ljwx-admin/src/components/common/CustomerSwitcher.vue @@ -1,5 +1,5 @@ + + \ No newline at end of file diff --git a/ljwx-admin/src/hooks/business/customer.ts b/ljwx-admin/src/hooks/business/customer.ts index d4f2835..26d3b50 100644 --- a/ljwx-admin/src/hooks/business/customer.ts +++ b/ljwx-admin/src/hooks/business/customer.ts @@ -1,7 +1,8 @@ import { computed } from 'vue'; import { useAuthStore } from '@/store/modules/auth'; import { useCustomerStore, type CustomerAccess } from '@/store/modules/customer'; -import { fetchGetAccessibleCustomers, fetchCustomerIdByOrgId } from '@/service/api/customer'; +import { fetchGetAllAvailableCustomers } from '@/service/api/customer/customer'; +import { fetchCustomerIdByOrgId } from '@/service/api'; /** * 客户业务逻辑 Hook @@ -11,7 +12,7 @@ export function useCustomer() { const customerStore = useCustomerStore(); // 当前用户角色 - const userRole = computed(() => authStore.userInfo?.roles?.[0] || ''); + const userRole = computed(() => authStore.userInfo?.roleIds?.[0] || ''); const userInfo = computed(() => authStore.userInfo); // 是否是 admin 用户 @@ -29,29 +30,38 @@ export function useCustomer() { if (isAdmin.value) { // admin 用户:可以切换客户,需要加载所有客户列表 - const { data } = await fetchGetAccessibleCustomers(); + const { data } = await fetchGetAllAvailableCustomers(); + const customerList = (data || []).map(item => ({ + id: item.customerId.toString(), // 转换为字符串避免精度问题 + name: item.customerName, + code: item.customerId.toString(), + status: 'ACTIVE', + description: `客户ID: ${item.customerId}` + })); + return { canSwitch: true, defaultCustomerId: null, // 需要手动选择 - customerList: data || [] + customerList }; } else { // 其他用户:不能切换,使用自己的客户ID let customerId = user.customerId; // 如果用户没有直接的 customerId,尝试通过 orgId 获取 - if (!customerId && user.orgId && Array.isArray(user.orgId) && user.orgId.length > 0) { - try { - const { data } = await fetchCustomerIdByOrgId(user.orgId[0]); - customerId = data.customerId; - } catch (error) { - console.error('根据组织ID获取客户ID失败:', error); - } - } + // 注意:如果用户类型定义中没有 orgId 字段,这部分逻辑需要调整 + // if (!customerId && user.orgId && Array.isArray(user.orgId) && user.orgId.length > 0) { + // try { + // const { data } = await fetchCustomerIdByOrgId(user.orgId[0]); + // customerId = data.customerId; + // } catch (error) { + // console.error('根据组织ID获取客户ID失败:', error); + // } + // } return { canSwitch: false, - defaultCustomerId: customerId || 0, + defaultCustomerId: customerId ? customerId.toString() : null, // 转换为字符串 customerList: [] }; } @@ -72,7 +82,8 @@ export function useCustomer() { customerStore.setCustomerAccess(access); // 如果有默认客户ID且当前没有设置,则设置默认值 - if (access.defaultCustomerId && !customerStore.currentCustomerId) { + // 注意:对于admin用户,优先使用localStorage中保存的customerId + if (!customerStore.currentCustomerId && access.defaultCustomerId) { customerStore.setCurrentCustomerId(access.defaultCustomerId); } @@ -116,7 +127,7 @@ export function useCustomer() { /** * 切换客户(仅超级管理员) */ - const switchCustomer = async (customerId: number) => { + const switchCustomer = async (customerId: string) => { // 改为字符串类型 if (!customerStore.canSwitchCustomer) { throw new Error('当前用户无权限切换客户'); } diff --git a/ljwx-admin/src/layouts/modules/global-header/index.vue b/ljwx-admin/src/layouts/modules/global-header/index.vue index b5a5f83..ecefd89 100644 --- a/ljwx-admin/src/layouts/modules/global-header/index.vue +++ b/ljwx-admin/src/layouts/modules/global-header/index.vue @@ -9,6 +9,7 @@ import GlobalSearch from '../global-search/index.vue'; import ThemeButton from './components/theme-button.vue'; import UserAvatar from './components/user-avatar.vue'; import CustomerSwitcher from '@/components/common/CustomerSwitcher.vue'; +import TenantInfo from '@/components/common/TenantInfo.vue'; defineOptions({ name: 'GlobalHeader' @@ -44,6 +45,7 @@ const { isFullscreen, toggle } = useFullscreen(); + diff --git a/ljwx-admin/src/router/elegant/imports.ts b/ljwx-admin/src/router/elegant/imports.ts index 3dd24bb..08bfeca 100644 --- a/ljwx-admin/src/router/elegant/imports.ts +++ b/ljwx-admin/src/router/elegant/imports.ts @@ -81,6 +81,7 @@ export const views: Record Promise import("@/views/monitor/system/index.vue"), "multi-menu_first_child": () => import("@/views/multi-menu/first_child/index.vue"), "multi-menu_second_child_home": () => import("@/views/multi-menu/second_child_home/index.vue"), + "system_customer-select": () => import("@/views/system/customer-select/index.vue"), "system_dynamic-menu": () => import("@/views/system/dynamic-menu/index.vue"), system_license: () => import("@/views/system/license/index.vue"), task: () => import("@/views/task/index.vue"), diff --git a/ljwx-admin/src/router/elegant/routes.ts b/ljwx-admin/src/router/elegant/routes.ts index 35df992..886519f 100644 --- a/ljwx-admin/src/router/elegant/routes.ts +++ b/ljwx-admin/src/router/elegant/routes.ts @@ -829,6 +829,15 @@ export const generatedRoutes: GeneratedRoute[] = [ i18nKey: 'route.system' }, children: [ + { + name: 'system_customer-select', + path: '/system/customer-select', + component: 'view.system_customer-select', + meta: { + title: 'system_customer-select', + i18nKey: 'route.system_customer-select' + } + }, { name: 'system_dynamic-menu', path: '/system/dynamic-menu', diff --git a/ljwx-admin/src/router/elegant/transform.ts b/ljwx-admin/src/router/elegant/transform.ts index 9640b22..4e372f1 100644 --- a/ljwx-admin/src/router/elegant/transform.ts +++ b/ljwx-admin/src/router/elegant/transform.ts @@ -255,6 +255,7 @@ const routeMap: RouteMap = { "multi-menu_second_child": "/multi-menu/second/child", "multi-menu_second_child_home": "/multi-menu/second/child/home", "system": "/system", + "system_customer-select": "/system/customer-select", "system_dynamic-menu": "/system/dynamic-menu", "system_license": "/system/license", "task": "/task", diff --git a/ljwx-admin/src/service/api/customer/customer.ts b/ljwx-admin/src/service/api/customer/customer.ts index 6021832..d092293 100644 --- a/ljwx-admin/src/service/api/customer/customer.ts +++ b/ljwx-admin/src/service/api/customer/customer.ts @@ -78,4 +78,14 @@ export function fetchRecordCustomerSwitch(data: { method: 'POST', data }); +} + +// =============== Customer Config APIs =============== + +/** 获取所有可用的客户列表(用于客户选择器) */ +export function fetchGetAllAvailableCustomers() { + return request>({ + url: '/t_customer_config/all-customers', + method: 'GET' + }); } \ No newline at end of file diff --git a/ljwx-admin/src/service/api/manage/org-units.ts b/ljwx-admin/src/service/api/manage/org-units.ts index da50e16..88df281 100644 --- a/ljwx-admin/src/service/api/manage/org-units.ts +++ b/ljwx-admin/src/service/api/manage/org-units.ts @@ -91,10 +91,12 @@ export function fetchDeleteOrgUnits(data: Api.Common.DeleteParams) { } /** get org page tree */ -export function fetchGetOrgUnitsTree(id: number) { +export function fetchGetOrgUnitsTree(id?: number) { + const params = id ? { id } : {}; return request({ - url: `/sys_org_units/tree?id=${id}`, - method: 'GET' + url: '/sys_org_units/tree', + method: 'GET', + params }); } diff --git a/ljwx-admin/src/service/request/index.ts b/ljwx-admin/src/service/request/index.ts index a15ea60..1de20cf 100644 --- a/ljwx-admin/src/service/request/index.ts +++ b/ljwx-admin/src/service/request/index.ts @@ -1,6 +1,7 @@ import type { AxiosResponse } from 'axios'; import { BACKEND_ERROR_CODE, REQUEST_LANGUAGE, createFlatRequest, createRequest } from '@sa/axios'; import { useAuthStore } from '@/store/modules/auth'; +import { useCustomerStore } from '@/store/modules/customer'; import { $t } from '@/locales'; import { localStg } from '@/utils/storage'; import { getServiceBaseURL } from '@/utils/service'; @@ -28,15 +29,35 @@ export const request = createFlatRequest config.url?.includes(excludeUrl)); + // 调试信息 + if (import.meta.env.DEV) { + console.log('[Request] customerId injection:', { + url: config.url, + method: config.method, + userCustomerId: authStore.userInfo.customerId, + selectedCustomerId: customerStore.currentCustomerId, + finalCustomerId: customerId, + userName: authStore.userInfo?.userName, + shouldAdd: shouldAddCustomerId + }); + } if (shouldAddCustomerId) { - const customerId = authStore.userInfo.customerId; if (config.method?.toLowerCase() === 'get') { // GET请求:添加到查询参数 diff --git a/ljwx-admin/src/store/modules/customer/index.ts b/ljwx-admin/src/store/modules/customer/index.ts index 86fed65..19899d6 100644 --- a/ljwx-admin/src/store/modules/customer/index.ts +++ b/ljwx-admin/src/store/modules/customer/index.ts @@ -1,10 +1,11 @@ import { defineStore } from 'pinia'; import { ref, computed } from 'vue'; import { SetupStoreId } from '@/enum'; -import { fetchGetCustomerList, fetchCustomerIdByOrgId } from '@/service/api'; +import { fetchGetAllAvailableCustomers } from '@/service/api/customer/customer'; +import { fetchCustomerIdByOrgId } from '@/service/api'; export interface CustomerInfo { - id: number; + id: string; // 改为字符串类型避免精度问题 name: string; code?: string; logo?: string; @@ -14,16 +15,16 @@ export interface CustomerInfo { export interface CustomerAccess { canSwitch: boolean; - defaultCustomerId: number | null; + defaultCustomerId: string | null; // 改为字符串类型 customerList: CustomerInfo[]; } export const useCustomerStore = defineStore(SetupStoreId.Customer, () => { // 状态 - const currentCustomerId = ref(null); + const currentCustomerId = ref(null); // 改为字符串类型 const customerList = ref([]); const canSwitchCustomer = ref(false); - const recentCustomers = ref([]); + const recentCustomers = ref([]); // 改为字符串数组 const loading = ref(false); // 计算属性 @@ -43,7 +44,7 @@ export const useCustomerStore = defineStore(SetupStoreId.Customer, () => { }); // Actions - const setCurrentCustomerId = (customerId: number | null) => { + const setCurrentCustomerId = (customerId: string | null) => { // 改为字符串类型 currentCustomerId.value = customerId; // 更新最近访问记录 @@ -56,7 +57,7 @@ export const useCustomerStore = defineStore(SetupStoreId.Customer, () => { // 持久化到 localStorage if (customerId) { - localStorage.setItem('currentCustomerId', customerId.toString()); + localStorage.setItem('currentCustomerId', customerId); // 直接存储字符串 localStorage.setItem('recentCustomers', JSON.stringify(recentCustomers.value)); } else { localStorage.removeItem('currentCustomerId'); @@ -77,14 +78,17 @@ export const useCustomerStore = defineStore(SetupStoreId.Customer, () => { try { loading.value = true; - const { data } = await fetchGetCustomerList({ - page: 1, - pageSize: 100, - status: 'ACTIVE' - }); + const { data } = await fetchGetAllAvailableCustomers(); - if (data?.records) { - customerList.value = data.records; + // 转换数据格式 + if (data) { + customerList.value = data.map(item => ({ + id: item.customerId.toString(), // 转换为字符串避免精度问题 + name: item.customerName, + code: item.customerId.toString(), + status: 'ACTIVE', // 接口返回的都是可用的客户 + description: `客户ID: ${item.customerId}` + })); } } catch (error) { console.error('加载客户列表失败:', error); @@ -93,7 +97,7 @@ export const useCustomerStore = defineStore(SetupStoreId.Customer, () => { } }; - const switchCustomer = async (customerId: number) => { + const switchCustomer = async (customerId: string) => { // 改为字符串类型 if (!canSwitchCustomer.value) { console.warn('当前用户无权限切换客户'); return; @@ -102,17 +106,26 @@ export const useCustomerStore = defineStore(SetupStoreId.Customer, () => { try { loading.value = true; + console.log('切换客户: customerId =', customerId); + // 设置新的客户ID setCurrentCustomerId(customerId); // 清理相关缓存 await clearCustomerRelatedCache(); - // 重新加载页面数据 - window.location.reload(); + // 显示成功消息 + const customerName = customerList.value.find(c => c.id === customerId)?.name || customerId; + window.$message?.success(`已切换到客户: ${customerName}`); + + // 延迟一下再重新加载页面,让用户看到成功消息 + setTimeout(() => { + window.location.reload(); + }, 500); } catch (error) { console.error('切换客户失败:', error); + window.$message?.error('切换客户失败'); throw error; } finally { loading.value = false; @@ -151,7 +164,7 @@ export const useCustomerStore = defineStore(SetupStoreId.Customer, () => { const savedRecentCustomers = localStorage.getItem('recentCustomers'); if (savedCustomerId) { - currentCustomerId.value = parseInt(savedCustomerId); + currentCustomerId.value = savedCustomerId; // 直接使用字符串,不进行数字转换 } if (savedRecentCustomers) { diff --git a/ljwx-admin/src/typings/components.d.ts b/ljwx-admin/src/typings/components.d.ts index e9449c5..440bde9 100644 --- a/ljwx-admin/src/typings/components.d.ts +++ b/ljwx-admin/src/typings/components.d.ts @@ -12,6 +12,7 @@ declare module 'vue' { ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default'] CountTo: typeof import('./../components/custom/count-to.vue')['default'] CustomerSelectionPrompt: typeof import('./../components/common/CustomerSelectionPrompt.vue')['default'] + CustomerSelector: typeof import('./../components/business/CustomerSelector.vue')['default'] CustomerSwitcher: typeof import('./../components/common/CustomerSwitcher.vue')['default'] DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default'] ExceptionBase: typeof import('./../components/common/exception-base.vue')['default'] @@ -129,6 +130,7 @@ declare module 'vue' { SystemLogo: typeof import('./../components/common/system-logo.vue')['default'] TableColumnSetting: typeof import('./../components/advanced/table-column-setting.vue')['default'] TableHeaderOperation: typeof import('./../components/advanced/table-header-operation.vue')['default'] + TenantInfo: typeof import('./../components/common/TenantInfo.vue')['default'] ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default'] WaveBg: typeof import('./../components/custom/wave-bg.vue')['default'] } diff --git a/ljwx-admin/src/typings/elegant-router.d.ts b/ljwx-admin/src/typings/elegant-router.d.ts index 11566ff..f8bf65e 100644 --- a/ljwx-admin/src/typings/elegant-router.d.ts +++ b/ljwx-admin/src/typings/elegant-router.d.ts @@ -109,6 +109,7 @@ declare module "@elegant-router/types" { "multi-menu_second_child": "/multi-menu/second/child"; "multi-menu_second_child_home": "/multi-menu/second/child/home"; "system": "/system"; + "system_customer-select": "/system/customer-select"; "system_dynamic-menu": "/system/dynamic-menu"; "system_license": "/system/license"; "task": "/task"; @@ -268,6 +269,7 @@ declare module "@elegant-router/types" { | "monitor_system" | "multi-menu_first_child" | "multi-menu_second_child_home" + | "system_customer-select" | "system_dynamic-menu" | "system_license" | "task" diff --git a/ljwx-admin/src/utils/auth.ts b/ljwx-admin/src/utils/auth.ts new file mode 100644 index 0000000..480084e --- /dev/null +++ b/ljwx-admin/src/utils/auth.ts @@ -0,0 +1,45 @@ +import { useAuthStore } from '@/store/modules/auth'; + +/** + * 检查用户是否有指定权限 + * @param permission 权限码,如 'license:management:import' + * @returns boolean + */ +export function hasPermission(permission: string): boolean { + const authStore = useAuthStore(); + + // 如果没有权限数组,返回 false + if (!authStore.userInfo.permissions || authStore.userInfo.permissions.length === 0) { + return false; + } + + // 检查权限数组中是否包含指定权限 + return authStore.userInfo.permissions.includes(permission); +} + +/** + * 检查用户是否有任意一个权限 + * @param permissions 权限码数组 + * @returns boolean + */ +export function hasAnyPermission(permissions: string[]): boolean { + return permissions.some(permission => hasPermission(permission)); +} + +/** + * 检查用户是否拥有所有指定权限 + * @param permissions 权限码数组 + * @returns boolean + */ +export function hasAllPermissions(permissions: string[]): boolean { + return permissions.every(permission => hasPermission(permission)); +} + +/** + * 检查用户是否为超级管理员 + * @returns boolean + */ +export function isSuperAdmin(): boolean { + const authStore = useAuthStore(); + return authStore.isStaticSuper; +} \ No newline at end of file diff --git a/ljwx-admin/src/utils/date.ts b/ljwx-admin/src/utils/date.ts index 77f275e..700f786 100644 --- a/ljwx-admin/src/utils/date.ts +++ b/ljwx-admin/src/utils/date.ts @@ -21,3 +21,14 @@ export function convertToBeijingTime(timestamp: dayjs.ConfigType) { export function formatDate(date: dayjs.ConfigType, format: string = 'YYYY-MM-DD') { return dayjs(date).format(format); } + +/** + * format time + * + * @param time time + * @param format format pattern, default is 'HH:mm:ss' + * @returns formatted time + */ +export function formatTime(time: dayjs.ConfigType, format: string = 'HH:mm:ss') { + return dayjs(time).format(format); +} diff --git a/ljwx-admin/src/views/manage/org/index.vue b/ljwx-admin/src/views/manage/org/index.vue index ea3db9f..2ce500a 100644 --- a/ljwx-admin/src/views/manage/org/index.vue +++ b/ljwx-admin/src/views/manage/org/index.vue @@ -48,8 +48,8 @@ const { columns, columnChecks, data, loading, getData, getDataByPage, mobilePagi page: 1, pageSize: 20, name: null, - status: null, - id: authStore.userInfo?.customerId // 使用用户的customerId作为orgId查询参数 + status: null + // customerId 将由请求拦截器自动添加 }, columns: () => [ { diff --git a/ljwx-admin/src/views/manage/user/modules/org-utils-tree.vue b/ljwx-admin/src/views/manage/user/modules/org-utils-tree.vue index 6b86892..81b69f7 100644 --- a/ljwx-admin/src/views/manage/user/modules/org-utils-tree.vue +++ b/ljwx-admin/src/views/manage/user/modules/org-utils-tree.vue @@ -40,7 +40,7 @@ const editingData: Ref = ref(null); /** init */ const init = async () => { - const { data, error } = await fetchGetOrgUnitsTree(authStore.userInfo?.customerId); + const { data, error } = await fetchGetOrgUnitsTree(); if (!error && data) { orgUnitsTreeData.value = data; } diff --git a/ljwx-admin/src/views/system/customer-select/index.vue b/ljwx-admin/src/views/system/customer-select/index.vue new file mode 100644 index 0000000..1ca150e --- /dev/null +++ b/ljwx-admin/src/views/system/customer-select/index.vue @@ -0,0 +1,200 @@ + + + + + + \ No newline at end of file diff --git a/ljwx-boot/ljwx-boot-admin/src/main/java/com/ljwx/admin/controller/customer/TCustomerConfigController.java b/ljwx-boot/ljwx-boot-admin/src/main/java/com/ljwx/admin/controller/customer/TCustomerConfigController.java index 35e3661..a4d0b6f 100644 --- a/ljwx-boot/ljwx-boot-admin/src/main/java/com/ljwx/admin/controller/customer/TCustomerConfigController.java +++ b/ljwx-boot/ljwx-boot-admin/src/main/java/com/ljwx/admin/controller/customer/TCustomerConfigController.java @@ -53,7 +53,9 @@ import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.time.LocalDateTime; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * Controller 控制层 @@ -365,5 +367,35 @@ public class TCustomerConfigController { return Result.failure("更新失败: " + e.getMessage()); } } + + /** + * 获取所有可用的客户列表(用于客户选择器) + */ + @GetMapping("/all-customers") + @Operation(operationId = "12", summary = "获取所有可用的客户列表") + public Result>> getAllAvailableCustomers() { + try { + List customerConfigs = tCustomerConfigService.list(); + + List> customers = customerConfigs.stream() + .filter(config -> config.getIsDeleted() == null || config.getIsDeleted() == 0) // 过滤未删除的 + .map(config -> { + Map customer = new HashMap<>(); + customer.put("customerId", config.getId()); + customer.put("customerName", config.getCustomerName()); + log.debug("Customer: id={}, name={}, isDeleted={}", + config.getId(), config.getCustomerName(), config.getIsDeleted()); + return customer; + }) + .collect(Collectors.toList()); + + log.info("获取可用客户列表成功,共{}个客户", customers.size()); + return Result.data(customers); + + } catch (Exception e) { + log.error("获取可用客户列表失败", e); + return Result.failure("获取客户列表失败: " + e.getMessage()); + } + } } \ No newline at end of file diff --git a/ljwx-boot/ljwx-boot-admin/src/main/java/com/ljwx/admin/controller/system/SysOrgUnitsController.java b/ljwx-boot/ljwx-boot-admin/src/main/java/com/ljwx/admin/controller/system/SysOrgUnitsController.java index 9c09af1..a3fdd68 100644 --- a/ljwx-boot/ljwx-boot-admin/src/main/java/com/ljwx/admin/controller/system/SysOrgUnitsController.java +++ b/ljwx-boot/ljwx-boot-admin/src/main/java/com/ljwx/admin/controller/system/SysOrgUnitsController.java @@ -54,6 +54,7 @@ public class SysOrgUnitsController { System.out.println(" id: " + sysOrgUnitsSearchDTO.getId()); System.out.println(" name: " + sysOrgUnitsSearchDTO.getName()); System.out.println(" status: " + sysOrgUnitsSearchDTO.getStatus()); + System.out.println(" customerId: " + sysOrgUnitsSearchDTO.getCustomerId()); return Result.data(sysOrgUnitsFacade.listSysOrgUnitsPage(pageQuery, sysOrgUnitsSearchDTO)); } @@ -93,8 +94,17 @@ public class SysOrgUnitsController { @GetMapping("/tree") @SaCheckPermission("sys:org:units:tree") @Operation(operationId = "6", summary = "获取租户/部门树结构数据") - public Result> tree(@RequestParam(value = "id", required = false) Long id) { - return Result.data(sysOrgUnitsFacade.queryAllOrgUnitsListConvertToTree(id)); + public Result> tree(@RequestParam(value = "id", required = false) Long id, + @RequestParam(value = "customerId", required = false) Long customerId) { + System.out.println("🔍 SysOrgUnitsController.tree - 接收到参数:"); + System.out.println(" id: " + id); + System.out.println(" customerId: " + customerId); + + // 如果传入了customerId,说明要按租户过滤,将customerId作为id进行查询 + Long effectiveId = (customerId != null) ? customerId : id; + System.out.println(" effectiveId: " + effectiveId); + + return Result.data(sysOrgUnitsFacade.queryAllOrgUnitsListConvertToTree(effectiveId)); } @PostMapping("/delete-precheck") diff --git a/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/domain/dto/org/units/SysOrgUnitsSearchDTO.java b/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/domain/dto/org/units/SysOrgUnitsSearchDTO.java index 4d2ceda..f022781 100644 --- a/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/domain/dto/org/units/SysOrgUnitsSearchDTO.java +++ b/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/domain/dto/org/units/SysOrgUnitsSearchDTO.java @@ -52,4 +52,7 @@ public class SysOrgUnitsSearchDTO implements Serializable { @Schema(description = "ID") private Long id; + @Schema(description = "客户ID") + private Long customerId; + } \ No newline at end of file diff --git a/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/facade/impl/SysOrgUnitsFacadeImpl.java b/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/facade/impl/SysOrgUnitsFacadeImpl.java index a863e9b..9c279b1 100644 --- a/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/facade/impl/SysOrgUnitsFacadeImpl.java +++ b/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/facade/impl/SysOrgUnitsFacadeImpl.java @@ -107,6 +107,12 @@ public class SysOrgUnitsFacadeImpl implements ISysOrgUnitsFacade { @Override public RPage listSysOrgUnitsPage(PageQuery pageQuery, SysOrgUnitsSearchDTO sysOrgUnitsSearchDTO) { SysOrgUnitsBO sysOrgUnitsBO = CglibUtil.convertObj(sysOrgUnitsSearchDTO, SysOrgUnitsBO::new); + + // 如果传入了customerId,说明要按租户过滤,将customerId作为id进行查询 + if (sysOrgUnitsSearchDTO.getCustomerId() != null) { + System.out.println("🔍 SysOrgUnitsFacadeImpl - 根据customerId过滤: " + sysOrgUnitsSearchDTO.getCustomerId()); + sysOrgUnitsBO.setId(sysOrgUnitsSearchDTO.getCustomerId()); + } IPage sysOrgUnitsIPage = sysOrgUnitsService.listSysOrgUnitsPage(pageQuery, sysOrgUnitsBO); List topOrgUnits = sysOrgUnitsIPage.getRecords(); if (topOrgUnits.isEmpty()) { diff --git a/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/listener/OrgUnitsChangeListener.java b/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/listener/OrgUnitsChangeListener.java index 609f9db..c9a8a70 100644 --- a/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/listener/OrgUnitsChangeListener.java +++ b/ljwx-boot/ljwx-boot-modules/src/main/java/com/ljwx/modules/system/listener/OrgUnitsChangeListener.java @@ -102,7 +102,9 @@ public class OrgUnitsChangeListener { interfaceService.remove(new QueryWrapper().eq("customer_id", o.getId())); // 先清理 List exists = interfaceService.list(new QueryWrapper().eq("customer_id", o.getId())); Set existNames = exists.stream().map(TInterface::getName).collect(Collectors.toSet()); - interfaceService.list(new QueryWrapper().eq("customer_id", 1).eq("is_deleted", 0)).stream() + List templateInterfaces = interfaceService.list(new QueryWrapper().eq("customer_id", 0).eq("is_deleted", 0)); + log.warn("Found {} template interfaces to clone", templateInterfaces.size()); + templateInterfaces.stream() .filter(i -> !existNames.contains(i.getName())) .forEach(i -> { log.warn("Inserting interface name={} for orgId={}", i.getName(), o.getId()); @@ -113,7 +115,7 @@ public class OrgUnitsChangeListener { TInterface n = new TInterface(); n.setName(i.getName()); n.setUrl(i.getUrl()); n.setCallInterval(i.getCallInterval()); n.setMethod(i.getMethod()); n.setDescription(i.getDescription()); n.setEnabled(i.getEnabled()); - n.setCustomerId(o.getId()); n.setDeleted(0); n.setCreateTime(i.getCreateTime()); n.setUpdateTime(i.getUpdateTime()); + n.setCustomerId(o.getId()); n.setIsDeleted(0); n.setCreateTime(i.getCreateTime()); n.setUpdateTime(i.getUpdateTime()); n.setApiAuth(i.getApiAuth()); n.setApiId(i.getApiId()); interfaceService.saveOrUpdate(n); @@ -123,7 +125,10 @@ public class OrgUnitsChangeListener { private void cloneHealthDataConfig(SysOrgUnits o) { // 复制健康数据配置 log.warn("cloneHealthDataConfig called for orgId={}", o.getId()); healthDataConfigService.remove(new QueryWrapper().eq("customer_id", o.getId())); // 先清理 - healthDataConfigService.list(new QueryWrapper().eq("customer_id", 1)).forEach(h -> { + List templateConfigs = healthDataConfigService.list(new QueryWrapper().eq("customer_id", 0).eq("is_deleted", 0)); + log.warn("Found {} template health data configs to clone", templateConfigs.size()); + templateConfigs.forEach(h -> { + log.warn("Cloning health data config: dataType={} for orgId={}", h.getDataType(), o.getId()); THealthDataConfig n = new THealthDataConfig(); n.setCustomerId(o.getId()); n.setDataType(h.getDataType()); n.setFrequencyInterval(h.getFrequencyInterval()); n.setIsRealtime(h.getIsRealtime()); n.setIsEnabled(h.getIsEnabled()); n.setIsDefault(h.getIsDefault()); diff --git a/monitoring-versions.env b/monitoring-versions.env index 8ea589c..394e615 100644 --- a/monitoring-versions.env +++ b/monitoring-versions.env @@ -2,12 +2,12 @@ # 更新时间: 2025-06-26 # 核心应用版本 -LJWX_VERSION=2.0.2 -LJWX_MYSQL_VERSION=2.0.2 -LJWX_REDIS_VERSION=2.0.2 -LJWX_BOOT_VERSION=2.0.2 -LJWX_BIGSCREEN_VERSION=2.0.2 -LJWX_ADMIN_VERSION=2.0.2 +LJWX_VERSION=2.0.3 +LJWX_MYSQL_VERSION=2.0.3 +LJWX_REDIS_VERSION=2.0.3 +LJWX_BOOT_VERSION=2.0.3 +LJWX_BIGSCREEN_VERSION=2.0.3 +LJWX_ADMIN_VERSION=2.0.3 # 定制化监控组件版本 LJWX_GRAFANA_VERSION=1.2.6