diff --git a/.env.development b/.env.development index ebab6e3..3dfa537 100644 --- a/.env.development +++ b/.env.development @@ -34,5 +34,9 @@ VITE_GLOB_PRINT_BASE_URL = http://114.116.210.204:3300 # 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换 VITE_GLOB_API_URL_PREFIX = +#租户开关 +VITE_TENANT_ENABLED = true # 屏蔽通知消息的轮询 VITE_DISABLE_NEWS=false +# 禁用关闭页面提示 +VITE_CLOSE_ALERT_DISABLED=true diff --git a/.env.production b/.env.production index 30bdf22..756250e 100644 --- a/.env.production +++ b/.env.production @@ -36,3 +36,5 @@ VITE_GLOB_API_URL_PREFIX = # 打包是否开启pwa功能 VITE_USE_PWA = false +#租户开关 +VITE_TENANT_ENABLED = true diff --git a/src/App.vue b/src/App.vue index 61cb7b8..377faad 100644 --- a/src/App.vue +++ b/src/App.vue @@ -19,6 +19,7 @@ import { computed } from 'vue'; import { getLogoInfo } from './api/system/login'; import { onBeforeUnmount } from 'vue'; + import {getAppEnvConfig} from "/@/utils/env"; // support Multi-language const { getLocale } = useLocale(); @@ -54,7 +55,9 @@ return '关闭提示'; }; - window.addEventListener('beforeunload', beforeUnloadHandler); + if(!getAppEnvConfig().VITE_CLOSE_ALERT_DISABLED){ + window.addEventListener('beforeunload', beforeUnloadHandler); + } onBeforeUnmount(() => { window.removeEventListener('beforeunload', beforeUnloadHandler); diff --git a/src/api/system/login/model/index.ts b/src/api/system/login/model/index.ts index 9891d35..b95ba73 100644 --- a/src/api/system/login/model/index.ts +++ b/src/api/system/login/model/index.ts @@ -6,6 +6,7 @@ import { DesktopData } from '/@/model/desktop/designer'; export interface LoginParams { userName: string; password: string; + tenantCode: string; deviceType?: number; } @@ -18,6 +19,9 @@ export interface RoleInfo { export type DepartmentInfo = RoleInfo; export type PostInfo = RoleInfo; + +export type TenantInfo = RoleInfo; + /** * @description: Login interface return value */ diff --git a/src/api/system/menu/index.ts b/src/api/system/menu/index.ts index 9729c86..7e620e6 100644 --- a/src/api/system/menu/index.ts +++ b/src/api/system/menu/index.ts @@ -9,6 +9,7 @@ enum Api { AllTree = '/system/menu/all-tree', jumpMenuTree = '/system/menu/child-tree', SimpleTree = '/system/menu/simple-tree', + TenantSimpleTree = '/system/menu/tenant-auth-tree', Menu = '/system/menu', Button = '/system/menu/button', Column = '/system/menu-colum/list', @@ -75,6 +76,24 @@ export async function getMenuSimpleTree(params?: MenuTreeParams, mode: ErrorMess ); } +/** + * @description: 查询菜单树 + */ +export async function getTenantMenuSimpleTree( + params?: MenuTreeParams, + mode: ErrorMessageMode = 'modal', +) { + return defHttp.get( + { + url: Api.TenantSimpleTree, + params, + }, + { + errorMessageMode: mode, + }, + ); +} + /** * @description: 删除菜单(批量删除) */ diff --git a/src/api/system/tenant/index.ts b/src/api/system/tenant/index.ts new file mode 100644 index 0000000..0d5c1f9 --- /dev/null +++ b/src/api/system/tenant/index.ts @@ -0,0 +1,193 @@ +import { defHttp } from '/@/utils/http/axios'; + +import { ErrorMessageMode } from '/#/axios'; +import { TenantModel, TenantPageListParams, TenantPageListParamsModel } from './model'; + +enum Api { + Page = '/system/tenant/page', + List = '/system/tenant/list', + Info = '/system/tenant/info', + Tenant = '/system/tenant', + Status = '/system/tenant/status', + Authorize = '/system/tenant/authorize', + Switch = '/system/switch-tenant', +} + +/** + * @description: 查询租户分页列表 + */ +export async function getTenantPageList( + params: TenantPageListParamsModel, + mode: ErrorMessageMode = 'modal', +) { + return defHttp.get( + { + url: Api.Page, + params, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 查询租户所有 不分页 + */ +export async function getTenantAllList(mode: ErrorMessageMode = 'modal') { + return defHttp.get( + { + url: Api.List, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 删除租户(批量删除) + */ +export async function deleteTenant(ids: string[], mode: ErrorMessageMode = 'modal') { + return defHttp.delete( + { + url: Api.Tenant, + data: ids, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 新增租户 + */ +export async function addTenant(role: Recordable, mode: ErrorMessageMode = 'modal') { + return defHttp.post( + { + url: Api.Tenant, + params: role, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 获取角色信息 + */ +export async function getTenant(id: string, mode: ErrorMessageMode = 'modal') { + return defHttp.get( + { + url: Api.Info, + params: { id }, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 更新租户 + */ +export async function updateTenant(role: Recordable, mode: ErrorMessageMode = 'modal') { + return defHttp.put( + { + url: Api.Tenant, + data: role, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 更新租户状态 + */ +export async function updateTenantStatus( + id: string, + status: number, + mode: ErrorMessageMode = 'modal', +) { + return defHttp.put( + { + url: Api.Status, + data: { + id, + enabledMark: status, + }, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 查询租户列表 + */ +export async function getTenantList( + params: { + keyword: string; + }, + mode: ErrorMessageMode = 'modal', +) { + return defHttp.get( + { + url: Api.List, + params, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 获取租户授权的菜单 + */ +export async function getAuthorize(id: string, mode: ErrorMessageMode = 'modal') { + return defHttp.get( + { + url: Api.Authorize, + params: { id }, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 设置租户功能权限 + */ +export async function setAuthorize(params: Recordable, mode: ErrorMessageMode = 'modal') { + return defHttp.post( + { + url: Api.Authorize, + params, + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 切换岗位 + */ +export async function changeTenant(tenantCode: String, mode: ErrorMessageMode = 'modal') { + return defHttp.post( + { + url: Api.Switch, + data: { tenantCode }, + }, + { + errorMessageMode: mode, + }, + ); +} diff --git a/src/api/system/tenant/model/index.ts b/src/api/system/tenant/model/index.ts new file mode 100644 index 0000000..443bc8e --- /dev/null +++ b/src/api/system/tenant/model/index.ts @@ -0,0 +1,36 @@ +import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel'; + +export interface TenantPageListParams { + name: string; //角色名 + code: string; //编号 + startTime: string; //租户开始时间 + endTime: string; //租户结束时间 + remark: string; //备注 +} + +export interface TenantInfo { + id: string; + name: string; //角色名 + code: string; //编号 + startTime: string; //租户开始时间 + endTime: string; //租户结束时间 + remark: string; //备注 +} +/** + * @description: Request list interface parameters + */ +export type TenantPageListParamsModel = BasicPageParams & TenantPageListParams; + +export interface TenantModel { + id: string; + name: string; //角色名 + code: string; //编号 + startTime: string; //租户开始时间 + endTime: string; //租户结束时间 + remark: string; //备注 +} + +/** + * @description: Request list return value + */ +export type RolePageListResultModel = BasicFetchResult; diff --git a/src/components/Application/index.ts b/src/components/Application/index.ts index 7569b02..e7eb628 100644 --- a/src/components/Application/index.ts +++ b/src/components/Application/index.ts @@ -6,6 +6,7 @@ import appSearch from './src/search/AppSearch.vue'; import appLocalePicker from './src/AppLocalePicker.vue'; import appDarkModeToggle from './src/AppDarkModeToggle.vue'; import userPostChange from './src/UserPostChange.vue'; +import userTenantChange from './src/UserTenantChange.vue'; export { useAppProviderContext } from './src/useAppContext'; export const AppLogo = withInstall(appLogo); @@ -14,3 +15,4 @@ export const AppSearch = withInstall(appSearch); export const AppLocalePicker = withInstall(appLocalePicker); export const AppDarkModeToggle = withInstall(appDarkModeToggle); export const UserPostChange = withInstall(userPostChange); +export const UserTenantChange = withInstall(userTenantChange); diff --git a/src/components/Application/src/UserTenantChange.vue b/src/components/Application/src/UserTenantChange.vue new file mode 100644 index 0000000..057c45f --- /dev/null +++ b/src/components/Application/src/UserTenantChange.vue @@ -0,0 +1,116 @@ + + + + diff --git a/src/components/DatePicker/src/DatePicker.vue b/src/components/DatePicker/src/DatePicker.vue index 4cc7044..c3f764e 100644 --- a/src/components/DatePicker/src/DatePicker.vue +++ b/src/components/DatePicker/src/DatePicker.vue @@ -1,58 +1,58 @@ diff --git a/src/components/Form/src/componentMap.ts b/src/components/Form/src/componentMap.ts index a63e746..5413b15 100644 --- a/src/components/Form/src/componentMap.ts +++ b/src/components/Form/src/componentMap.ts @@ -99,6 +99,7 @@ componentMap.set('CheckboxGroup', Checkbox.Group); componentMap.set('ApiCascader', ApiCascader); componentMap.set('Slider', Slider); componentMap.set('Rate', Rate); +componentMap.set('DeptTree', SelectDepartment); componentMap.set('Dept', SelectDepartmentV2); componentMap.set('User', SelectUserV2); componentMap.set('Info', CommonInfo); diff --git a/src/components/Form/src/types/index.ts b/src/components/Form/src/types/index.ts index bfe2020..2dba25c 100644 --- a/src/components/Form/src/types/index.ts +++ b/src/components/Form/src/types/index.ts @@ -124,6 +124,7 @@ export type ComponentType = | 'Card' | 'ChildTable' | 'Divider' + | 'DeptTree' | 'Dept' | 'User' | 'Info' diff --git a/src/components/SystemForm/src/Form.vue b/src/components/SystemForm/src/Form.vue index 7a645fd..9ad4e5d 100644 --- a/src/components/SystemForm/src/Form.vue +++ b/src/components/SystemForm/src/Form.vue @@ -178,7 +178,12 @@ let id = await submit(saveRowKey); let rowKey = getRowKey(); values[rowKey] = id; - values['_id'] = id + values['_id'] = id; + //重新查一遍 + let newValues=await SystemFormRef.value.setFormDataFromId(id); + if(newValues){ + values=newValues; + } } return values; diff --git a/src/layouts/default/header/components/childSystem.vue b/src/layouts/default/header/components/childSystem.vue index ea8f68e..a0ab452 100644 --- a/src/layouts/default/header/components/childSystem.vue +++ b/src/layouts/default/header/components/childSystem.vue @@ -88,6 +88,9 @@ onMounted(async () => { await permissionStore.changeSubsystem(getShowTopMenu.value, getIsMobile.value); system.value = permissionStore.getSubSysList; + if(system.value.length>0){ + changeSystem(system.value[0].id); + } }); //切换系统 diff --git a/src/layouts/default/header/index.vue b/src/layouts/default/header/index.vue index 87962be..6bd3edf 100644 --- a/src/layouts/default/header/index.vue +++ b/src/layouts/default/header/index.vue @@ -25,7 +25,7 @@ - + @@ -49,7 +49,7 @@ import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum'; import { SettingButtonPositionEnum } from '/@/enums/appEnum'; - import { UserPostChange } from '/@/components/Application'; + import { UserTenantChange } from '/@/components/Application'; import { LayoutBreadcrumb, Notify, ErrorAction } from './components'; import UserDropDown from '/@/layouts/default/header/components/user-dropdown/DropDown.vue'; @@ -58,9 +58,11 @@ import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; import { useLocale } from '/@/locales/useLocale'; + import {getAppEnvConfig} from "/@/utils/env"; export default defineComponent({ name: 'LayoutHeader', + methods: {getAppEnvConfig}, components: { LayHeader: Layout.Header, AppLogo, @@ -74,7 +76,7 @@ SettingDrawer: createAsyncComponent(() => import('/@/layouts/default/setting/index.vue'), { loading: true }), - UserPostChange + UserTenantChange }, props: { fixed: propTypes.bool diff --git a/src/utils/helper/generatorHelper.ts b/src/utils/helper/generatorHelper.ts index 1f9a15c..ae2080b 100644 --- a/src/utils/helper/generatorHelper.ts +++ b/src/utils/helper/generatorHelper.ts @@ -1725,6 +1725,7 @@ export function buildSimpleFormCode(model: GeneratorConfig, _tableInfo: TableInf await getFormDataEvent(formEventConfigs, state.formModel, systemFormRef.value, formProps.schemas); //表单事件:获取表单数据 + return record; } catch (error) { } diff --git a/src/views/secondDev/LoginForm.vue b/src/views/secondDev/LoginForm.vue index ff76ab2..513d8ef 100644 --- a/src/views/secondDev/LoginForm.vue +++ b/src/views/secondDev/LoginForm.vue @@ -18,6 +18,20 @@ + + + + + + @@ -59,6 +73,7 @@ import IconFontSymbol from '/@/components/IconFontSymbol/Index.vue'; import { useRouter } from 'vue-router'; + import { getAppEnvConfig } from '/@/utils/env'; const ACol = Col; const ARow = Row; @@ -81,7 +96,8 @@ const formData = reactive({ account: 'admin', - password: '123456' + password: 'YUdean@2024', + tenantCode: 'system' }); onMounted(async () => { @@ -122,6 +138,7 @@ if (loginInfo) { formData.account = Base64.decode(JSON.parse(loginInfo).account); formData.password = Base64.decode(JSON.parse(loginInfo).password); + formData.tenantCode = Base64.decode(JSON.parse(loginInfo).tenantCode); } }); @@ -139,6 +156,7 @@ const userInfo = await userStore.login({ password: data.password, userName: data.account, + tenantCode: data.tenantCode, deviceType: 0, //pc-0,app-1 mode: 'none' //不要默认的错误提示 }); @@ -151,7 +169,8 @@ if (rememberMe.value) { const info = { account: Base64.encode(data.account), - password: Base64.encode(data.password) + password: Base64.encode(data.password), + tenantCode: Base64.encode(data.tenantCode) }; window.localStorage.setItem('USER__LOGIN__INFO__', JSON.stringify(info)); } else { diff --git a/src/views/sys/login/LoginForm.vue b/src/views/sys/login/LoginForm.vue index 0ad5c38..eec158d 100644 --- a/src/views/sys/login/LoginForm.vue +++ b/src/views/sys/login/LoginForm.vue @@ -35,6 +35,19 @@ + + + + + @@ -117,6 +130,7 @@ import IconFontSymbol from '/@/components/IconFontSymbol/Index.vue'; import { getOauthAuthorizeUrl } from '/@/api/system/login'; import { useRouter } from 'vue-router'; + import { getAppEnvConfig } from '/@/utils/env'; // import { nextTick } from 'vue'; const ACol = Col; @@ -144,6 +158,7 @@ const formData = reactive({ account: 'admin', password: '123456', + tenantCode: 'system', }); onMounted(async () => { @@ -202,6 +217,7 @@ const userInfo = await userStore.login({ password: data.password, userName: data.account, + tenantCode: data.tenantCode, deviceType: 0, //pc-0,app-1 mode: 'none', //不要默认的错误提示 }); diff --git a/src/views/system/tenant/components/AuthModal.vue b/src/views/system/tenant/components/AuthModal.vue new file mode 100644 index 0000000..3d3ce2b --- /dev/null +++ b/src/views/system/tenant/components/AuthModal.vue @@ -0,0 +1,112 @@ + + diff --git a/src/views/system/tenant/components/TenantDrawer.vue b/src/views/system/tenant/components/TenantDrawer.vue new file mode 100644 index 0000000..3455493 --- /dev/null +++ b/src/views/system/tenant/components/TenantDrawer.vue @@ -0,0 +1,143 @@ + + diff --git a/src/views/system/tenant/index.vue b/src/views/system/tenant/index.vue new file mode 100644 index 0000000..a129165 --- /dev/null +++ b/src/views/system/tenant/index.vue @@ -0,0 +1,222 @@ + + diff --git a/types/config.d.ts b/types/config.d.ts index 32bc1bf..7138877 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -139,6 +139,7 @@ export interface GlobConfig { urlPrefix?: string; // Project abbreviation shortName: string; + tenantEnabled: boolean; // outlink outLink?: string; //print url @@ -160,6 +161,8 @@ export interface GlobEnvConfig { //file preview VITE_GLOB_UPLOAD_PREVIEW?: string; VITE_GLOB_REPORT_URL: string; + VITE_TENANT_ENABLED: boolean; + VITE_CLOSE_ALERT_DISABLED: boolean; } export interface LogoConfig { diff --git a/types/store.d.ts b/types/store.d.ts index f7dc432..81d0753 100644 --- a/types/store.d.ts +++ b/types/store.d.ts @@ -1,6 +1,7 @@ import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; import { RoleInfo } from '/@/api/sys/model/userModel'; +import {TenantInfo} from "/@/api/system/login/model"; // Lock screen information export interface LockInfo { @@ -66,7 +67,14 @@ export interface UserInfo { postId: string; //岗位名称 postName: string; + //租户id + tenantId: string; + //租户名称 + tenantName: string; + //租户编码 + tenantCode: string; + tenants: TenantInfo[]; //所有部门 departments: DepartmentInfo[]; //所有部门