mirror of
https://gitee.com/bootx/dax-pay-ui.git
synced 2025-09-06 04:09:36 +00:00
站内支持API接口地址切换 (#3162)
* feat: 站内切换接口API * feat: 站内切换接口API * feat: 站内支持API接口地址切换,解决冲突,新增开关显示 (cherry picked from commit c6d60b6cfd50bf8e19233a21640ecf1d41c01cc8)
This commit is contained in:
@@ -11,6 +11,7 @@ export const ROLES_KEY = 'ROLES__KEY__';
|
||||
|
||||
// project config key
|
||||
export const PROJ_CFG_KEY = 'PROJ__CFG__KEY__';
|
||||
export const API_ADDRESS = 'API_ADDRESS__';
|
||||
|
||||
// lock info
|
||||
export const LOCK_INFO_KEY = 'LOCK__INFO__KEY__';
|
||||
|
@@ -48,6 +48,8 @@ export function useHeaderSetting() {
|
||||
|
||||
const getShowDoc = computed(() => appStore.getHeaderSetting.showDoc);
|
||||
|
||||
const getShowApi = computed(() => appStore.getHeaderSetting.showApi);
|
||||
|
||||
const getHeaderTheme = computed(() => appStore.getHeaderSetting.theme);
|
||||
|
||||
const getShowHeader = computed(() => appStore.getHeaderSetting.show);
|
||||
@@ -86,6 +88,7 @@ export function useHeaderSetting() {
|
||||
setHeaderSetting,
|
||||
|
||||
getShowDoc,
|
||||
getShowApi,
|
||||
getShowSearch,
|
||||
getHeaderTheme,
|
||||
getUseLockPage,
|
||||
|
82
src/layouts/default/header/components/ChangeApi/index.vue
Normal file
82
src/layouts/default/header/components/ChangeApi/index.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
:title="t('layout.header.dropdownChangeApi')"
|
||||
v-bind="$attrs"
|
||||
@register="register"
|
||||
@ok="handelSubmit"
|
||||
@cancel="handelCancel"
|
||||
>
|
||||
<BasicForm @register="registerForm">
|
||||
<template #api="{ model, field }">
|
||||
<RadioGroup v-model:value="model[field]">
|
||||
<Radio :style="radioStyle" :value="key" v-for="(val, key) in addresses" :key="key"
|
||||
>{{ key }}: {{ val }}</Radio
|
||||
>
|
||||
</RadioGroup>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { Radio } from 'ant-design-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal/index';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { ref } from 'vue';
|
||||
import { useAppStore } from '/@/store/modules/app';
|
||||
import type { ApiAddress } from '/#/store';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const RadioGroup = Radio.Group;
|
||||
const { t } = useI18n();
|
||||
const [register, { closeModal }] = useModalInner(async () => {
|
||||
initData();
|
||||
});
|
||||
// perf 能读取所有.env.xxx文件最好, 另外key与--mode XXX最好相同
|
||||
const addresses = ref({
|
||||
development: 'http://www.a.com',
|
||||
test: 'http://www.b.com',
|
||||
prod: 'http://www.c.com',
|
||||
});
|
||||
const radioStyle = ref({
|
||||
display: 'flex',
|
||||
height: '30px',
|
||||
lineHeight: '30px',
|
||||
});
|
||||
const [registerForm, { validateFields, setFieldsValue }] = useForm({
|
||||
showActionButtonGroup: false,
|
||||
schemas: [
|
||||
{
|
||||
field: 'api',
|
||||
label: t('layout.header.dropdownChangeApi'),
|
||||
colProps: {
|
||||
span: 24,
|
||||
},
|
||||
defaultValue: import.meta.env.MODE || 'development', // 当前环境
|
||||
required: true,
|
||||
component: 'Input',
|
||||
slot: 'api',
|
||||
},
|
||||
],
|
||||
});
|
||||
const handelSubmit = async () => {
|
||||
const values = await validateFields();
|
||||
appStore.setApiAddress({
|
||||
key: values.api,
|
||||
val: addresses.value[values.api],
|
||||
});
|
||||
location.reload();
|
||||
};
|
||||
const handelCancel = () => {
|
||||
closeModal();
|
||||
};
|
||||
const initData = () => {
|
||||
const { key = '' } = appStore.getApiAddress as ApiAddress;
|
||||
if (key) {
|
||||
setFieldsValue({
|
||||
api: key,
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="less"></style>
|
@@ -18,6 +18,12 @@
|
||||
v-if="getShowDoc"
|
||||
/>
|
||||
<MenuDivider v-if="getShowDoc" />
|
||||
<MenuItem
|
||||
v-if="getShowApi"
|
||||
key="api"
|
||||
:text="t('layout.header.dropdownChangeApi')"
|
||||
icon="ant-design:swap-outlined"
|
||||
/>
|
||||
<MenuItem
|
||||
v-if="getUseLockPage"
|
||||
key="lock"
|
||||
@@ -33,6 +39,7 @@
|
||||
</template>
|
||||
</Dropdown>
|
||||
<LockAction @register="register" />
|
||||
<ChangeApi @register="registerApi" />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
// components
|
||||
@@ -55,7 +62,7 @@
|
||||
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
|
||||
type MenuEvent = 'logout' | 'doc' | 'lock';
|
||||
type MenuEvent = 'logout' | 'doc' | 'lock' | 'api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'UserDropdown',
|
||||
@@ -65,6 +72,7 @@
|
||||
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
|
||||
MenuDivider: Menu.Divider,
|
||||
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
|
||||
ChangeApi: createAsyncComponent(() => import('../ChangeApi/index.vue')),
|
||||
},
|
||||
props: {
|
||||
theme: propTypes.oneOf(['dark', 'light']),
|
||||
@@ -72,7 +80,7 @@
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('header-user-dropdown');
|
||||
const { t } = useI18n();
|
||||
const { getShowDoc, getUseLockPage } = useHeaderSetting();
|
||||
const { getShowDoc, getUseLockPage, getShowApi } = useHeaderSetting();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const getUserInfo = computed(() => {
|
||||
@@ -81,11 +89,16 @@
|
||||
});
|
||||
|
||||
const [register, { openModal }] = useModal();
|
||||
const [registerApi, { openModal: openApiModal }] = useModal();
|
||||
|
||||
function handleLock() {
|
||||
openModal(true);
|
||||
}
|
||||
|
||||
function handleApi() {
|
||||
openApiModal(true, {});
|
||||
}
|
||||
|
||||
// login out
|
||||
function handleLoginOut() {
|
||||
userStore.confirmLoginOut();
|
||||
@@ -107,6 +120,9 @@
|
||||
case 'lock':
|
||||
handleLock();
|
||||
break;
|
||||
case 'api':
|
||||
handleApi();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +132,9 @@
|
||||
getUserInfo,
|
||||
handleMenuClick,
|
||||
getShowDoc,
|
||||
getShowApi,
|
||||
register,
|
||||
registerApi,
|
||||
getUseLockPage,
|
||||
};
|
||||
},
|
||||
|
@@ -4,6 +4,7 @@
|
||||
"onlineDocument": "Document"
|
||||
},
|
||||
"header": {
|
||||
"dropdownChangeApi": "Change Api",
|
||||
"dropdownItemDoc": "Document",
|
||||
"dropdownItemLoginOut": "Log Out",
|
||||
"tooltipErrorLog": "Error log",
|
||||
|
@@ -4,6 +4,7 @@
|
||||
"onlineDocument": "在线文档"
|
||||
},
|
||||
"header": {
|
||||
"dropdownChangeApi": "切换API",
|
||||
"dropdownItemDoc": "文档",
|
||||
"dropdownItemLoginOut": "退出系统",
|
||||
"tooltipErrorLog": "错误日志",
|
||||
|
@@ -74,6 +74,7 @@ const setting: ProjectConfig = {
|
||||
showNotice: true,
|
||||
// Whether to display the menu search
|
||||
showSearch: true,
|
||||
showApi: true,
|
||||
},
|
||||
|
||||
// Menu configuration
|
||||
|
@@ -5,13 +5,13 @@ import type {
|
||||
TransitionSetting,
|
||||
MultiTabsSetting,
|
||||
} from '/#/config';
|
||||
import type { BeforeMiniState } from '/#/store';
|
||||
import type { BeforeMiniState, ApiAddress } from '/#/store';
|
||||
|
||||
import { defineStore } from 'pinia';
|
||||
import { store } from '/@/store';
|
||||
|
||||
import { ThemeEnum } from '/@/enums/appEnum';
|
||||
import { APP_DARK_MODE_KEY, PROJ_CFG_KEY } from '/@/enums/cacheEnum';
|
||||
import { APP_DARK_MODE_KEY, PROJ_CFG_KEY, API_ADDRESS } from '/@/enums/cacheEnum';
|
||||
import { Persistent } from '/@/utils/cache/persistent';
|
||||
import { darkMode } from '/@/settings/designSetting';
|
||||
import { resetRouter } from '/@/router';
|
||||
@@ -63,6 +63,9 @@ export const useAppStore = defineStore({
|
||||
getMultiTabsSetting(): MultiTabsSetting {
|
||||
return this.getProjectConfig.multiTabsSetting;
|
||||
},
|
||||
getApiAddress() {
|
||||
return JSON.parse(localStorage.getItem(API_ADDRESS) || '{}');
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setPageLoading(loading: boolean): void {
|
||||
@@ -103,6 +106,9 @@ export const useAppStore = defineStore({
|
||||
clearTimeout(timeId);
|
||||
}
|
||||
},
|
||||
setApiAddress(config: ApiAddress): void {
|
||||
localStorage.setItem(API_ADDRESS, JSON.stringify(config));
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import type { GlobEnvConfig } from '/#/config';
|
||||
import pkg from '../../package.json';
|
||||
import { API_ADDRESS } from '/@/enums/cacheEnum';
|
||||
|
||||
export function getCommonStoragePrefix() {
|
||||
const { VITE_GLOB_APP_TITLE } = getAppEnvConfig();
|
||||
@@ -29,9 +30,12 @@ export function getAppEnvConfig() {
|
||||
? // Get the global configuration (the configuration will be extracted independently when packaging)
|
||||
(import.meta.env as unknown as GlobEnvConfig)
|
||||
: (window[ENV_NAME] as unknown as GlobEnvConfig);
|
||||
const { VITE_GLOB_APP_TITLE, VITE_GLOB_API_URL, VITE_GLOB_API_URL_PREFIX, VITE_GLOB_UPLOAD_URL } =
|
||||
ENV;
|
||||
|
||||
const { VITE_GLOB_APP_TITLE, VITE_GLOB_API_URL_PREFIX, VITE_GLOB_UPLOAD_URL } = ENV;
|
||||
let { VITE_GLOB_API_URL } = ENV;
|
||||
if (localStorage.getItem(API_ADDRESS)) {
|
||||
const address = JSON.parse(localStorage.getItem(API_ADDRESS) || '{}');
|
||||
if (address?.key) VITE_GLOB_API_URL = address?.val;
|
||||
}
|
||||
return {
|
||||
VITE_GLOB_APP_TITLE,
|
||||
VITE_GLOB_API_URL,
|
||||
|
1
types/config.d.ts
vendored
1
types/config.d.ts
vendored
@@ -57,6 +57,7 @@ export interface HeaderSetting {
|
||||
// Show message center button
|
||||
showNotice: boolean;
|
||||
showSearch: boolean;
|
||||
showApi: boolean;
|
||||
}
|
||||
|
||||
export interface LocaleSetting {
|
||||
|
5
types/store.d.ts
vendored
5
types/store.d.ts
vendored
@@ -10,6 +10,11 @@ export interface LockInfo {
|
||||
isLock?: boolean;
|
||||
}
|
||||
|
||||
export interface ApiAddress {
|
||||
key: string;
|
||||
val: string;
|
||||
}
|
||||
|
||||
// Error-log information
|
||||
export interface ErrorLogInfo {
|
||||
// Type of error
|
||||
|
Reference in New Issue
Block a user