feat(license): 用户限制&部分 bug 修复
This commit is contained in:
parent
896520a8be
commit
44231d851a
|
@ -4,11 +4,18 @@ import { useI18n } from '@/hooks/useI18n';
|
|||
import useUser from '@/hooks/useUser';
|
||||
import router from '@/router';
|
||||
import { NO_RESOURCE_ROUTE_NAME } from '@/router/constants';
|
||||
import useLicenseStore from '@/store/modules/setting/license';
|
||||
|
||||
import type { ErrorMessageMode } from '#/axios';
|
||||
|
||||
export default function checkStatus(status: number, msg: string, errorMessageMode: ErrorMessageMode = 'message'): void {
|
||||
export default function checkStatus(
|
||||
status: number,
|
||||
msg: string,
|
||||
code?: number,
|
||||
errorMessageMode: ErrorMessageMode = 'message'
|
||||
): void {
|
||||
const { t } = useI18n();
|
||||
const licenseStore = useLicenseStore();
|
||||
const { logout, isLoginPage, isWhiteListPage } = useUser();
|
||||
let errMessage = '';
|
||||
switch (status) {
|
||||
|
@ -39,6 +46,77 @@ export default function checkStatus(status: number, msg: string, errorMessageMod
|
|||
errMessage = msg || t('api.errMsg408');
|
||||
break;
|
||||
case 500:
|
||||
if (code === 101511) {
|
||||
// 开源版创建用户超数量
|
||||
Message.error({
|
||||
content: () =>
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
style: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '4px',
|
||||
},
|
||||
},
|
||||
[
|
||||
h('span', t('user.openSourceCreateUsersLimit')),
|
||||
h(
|
||||
'a',
|
||||
{
|
||||
href: 'https://jinshuju.net/f/CzzAOe',
|
||||
target: '_blank',
|
||||
style: {
|
||||
color: 'rgb(var(--primary-5))',
|
||||
},
|
||||
},
|
||||
t('user.businessTry')
|
||||
),
|
||||
]
|
||||
),
|
||||
duration: 0,
|
||||
closable: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (code === 101512) {
|
||||
// 企业版创建用户超数量
|
||||
Message.error({
|
||||
content: () =>
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
style: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '4px',
|
||||
},
|
||||
},
|
||||
[
|
||||
h(
|
||||
'span',
|
||||
(licenseStore.licenseInfo?.license.count || 30) <= 30
|
||||
? t('user.businessCreateUsersLimitThirty')
|
||||
: t('user.businessCreateUsersLimitMax', { count: licenseStore.licenseInfo?.license.count })
|
||||
),
|
||||
h(
|
||||
'a',
|
||||
{
|
||||
href: 'https://jinshuju.net/f/CzzAOe',
|
||||
target: '_blank',
|
||||
style: {
|
||||
color: 'rgb(var(--primary-5))',
|
||||
},
|
||||
},
|
||||
t('user.businessScaling')
|
||||
),
|
||||
]
|
||||
),
|
||||
duration: 0,
|
||||
closable: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
errMessage = msg || t('api.errMsg500');
|
||||
break;
|
||||
case 501:
|
||||
|
|
|
@ -7,6 +7,7 @@ import { deepMerge, setObjToUrlParams } from '@/utils';
|
|||
import { getToken } from '@/utils/auth';
|
||||
import { isString } from '@/utils/is';
|
||||
|
||||
import type CommonResponse from '@/models/common';
|
||||
import { ContentTypeEnum, RequestEnum } from '@/enums/httpEnum';
|
||||
|
||||
import { MSAxios } from './Axios';
|
||||
|
@ -135,7 +136,7 @@ const transform: AxiosTransform = {
|
|||
/**
|
||||
* @description: 响应拦截器处理
|
||||
*/
|
||||
responseInterceptors: (res: AxiosResponse<any>) => {
|
||||
responseInterceptors: (res: AxiosResponse<CommonResponse<any>>) => {
|
||||
return res;
|
||||
},
|
||||
|
||||
|
@ -169,8 +170,8 @@ const transform: AxiosTransform = {
|
|||
} catch (e) {
|
||||
throw new Error(e as unknown as string);
|
||||
}
|
||||
checkStatus(error?.response?.status, msg, errorMessageMode);
|
||||
return Promise.reject(error?.response?.data?.message || error);
|
||||
checkStatus(response?.status, msg, response?.data?.code, errorMessageMode);
|
||||
return Promise.reject(response?.data?.message || error);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useLicenseStore from '@/store/modules/setting/license';
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
|
|
@ -30,4 +30,13 @@ export default {
|
|||
'asyncTask.uploadFileProgress': 'File upload progress {percent}; {done} successful, {fail} failed',
|
||||
'asyncTask.uploadFileSuccess': 'File upload completed: {done} successfully, {fail} failed',
|
||||
'asyncTask.uploadFileSuccessTitle': 'Upload completed',
|
||||
// 通用业务提示
|
||||
'user.openSourceCreateUsersLimit':
|
||||
'The maximum number of system users has reached 30 (Community Edition). If you need to add more users, you can apply',
|
||||
'user.businessTry': 'Enterprise Edition Trial',
|
||||
'user.businessCreateUsersLimitThirty':
|
||||
'The maximum number of system users has reached 30 (Community Edition). If you need to add more users, you can apply',
|
||||
'user.businessCreateUsersLimitMax':
|
||||
'The number of system users has reached the maximum number of user subscriptions {count}. If you want to add more users, you can apply',
|
||||
'user.businessScaling': 'Enterprise Edition Capacity Expansion',
|
||||
};
|
||||
|
|
|
@ -30,4 +30,10 @@ export default {
|
|||
'asyncTask.uploadFileProgress': '文件上传进度 {percent};成功 {done} 个,失败 {fail} 个',
|
||||
'asyncTask.uploadFileSuccess': '文件上传完成:成功 {done} 个,失败 {fail} 个',
|
||||
'asyncTask.uploadFileSuccessTitle': '上传完成',
|
||||
// 通用业务提示
|
||||
'user.openSourceCreateUsersLimit': '系统用户数已达到最大用户数限制30人(社区版),如需添加更多用户,可申请',
|
||||
'user.businessTry': '企业版试用',
|
||||
'user.businessCreateUsersLimitThirty': '系统用户数已达到最大用户数限制30人 (社区版),如需添加更多用户,可申请',
|
||||
'user.businessCreateUsersLimitMax': '系统用户数已达到最大用户订阅数 {count} 人,如需添加更多用户,可申请',
|
||||
'user.businessScaling': '企业版扩容',
|
||||
};
|
||||
|
|
|
@ -8,6 +8,6 @@ export interface License {
|
|||
}
|
||||
|
||||
export interface LicenseInfo {
|
||||
status: string;
|
||||
status: string | null;
|
||||
license: License;
|
||||
}
|
||||
|
|
|
@ -3,22 +3,26 @@ import dayjs from 'dayjs';
|
|||
|
||||
import { getLicenseInfo } from '@/api/modules/setting/authorizedManagement';
|
||||
|
||||
import type { LicenseInfo } from '@/models/setting/authorizedManagement';
|
||||
|
||||
const useLicenseStore = defineStore('license', {
|
||||
persist: true,
|
||||
state: (): { status: string | null; expiredDuring: boolean; expiredDays: number } => ({
|
||||
status: '',
|
||||
state: (): { licenseInfo: LicenseInfo | null; expiredDuring: boolean; expiredDays: number } => ({
|
||||
licenseInfo: null,
|
||||
expiredDuring: false,
|
||||
expiredDays: 0,
|
||||
}),
|
||||
actions: {
|
||||
setLicenseStatus(status: string) {
|
||||
this.status = status;
|
||||
setLicenseInfo(info: LicenseInfo) {
|
||||
this.licenseInfo = info;
|
||||
},
|
||||
removeLicenseStatus() {
|
||||
this.status = null;
|
||||
if (this.licenseInfo) {
|
||||
this.licenseInfo.status = null;
|
||||
}
|
||||
},
|
||||
hasLicense() {
|
||||
return this.status === 'valid';
|
||||
return this.licenseInfo?.status === 'valid';
|
||||
},
|
||||
getExpirationTime(resTime: string) {
|
||||
const today = Date.now();
|
||||
|
@ -42,10 +46,11 @@ const useLicenseStore = defineStore('license', {
|
|||
if (!result || !result.status || !result.license || !result.license.count) {
|
||||
return;
|
||||
}
|
||||
this.setLicenseStatus(result.status);
|
||||
this.setLicenseInfo(result);
|
||||
// 计算license时间
|
||||
this.getExpirationTime(result.license.expired);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1254,14 +1254,15 @@
|
|||
saveLoading.value = true;
|
||||
}
|
||||
let params;
|
||||
const requestParams = makeRequestParams();
|
||||
if (props.isDefinition) {
|
||||
params = {
|
||||
...(fullParams || makeRequestParams()),
|
||||
...(fullParams || requestParams),
|
||||
...props.otherParams,
|
||||
};
|
||||
} else {
|
||||
params = {
|
||||
...(fullParams || makeRequestParams()),
|
||||
...(fullParams || requestParams),
|
||||
...saveModalForm.value,
|
||||
path: isHttpProtocol.value ? saveModalForm.value.path : undefined,
|
||||
...props.otherParams,
|
||||
|
@ -1280,6 +1281,17 @@
|
|||
requestVModel.value.url = res.path;
|
||||
requestVModel.value.path = res.path;
|
||||
requestVModel.value.moduleId = res.moduleId;
|
||||
if (!isHttpProtocol.value) {
|
||||
requestVModel.value = {
|
||||
...requestVModel.value,
|
||||
...fApi.value?.formData(), // 存储插件表单数据
|
||||
uploadFileIds: requestParams.uploadFileIds,
|
||||
linkFileIds: requestParams.linkFileIds,
|
||||
};
|
||||
} else {
|
||||
requestVModel.value.uploadFileIds = requestParams.uploadFileIds;
|
||||
requestVModel.value.linkFileIds = requestParams.linkFileIds;
|
||||
}
|
||||
if (!props.isDefinition) {
|
||||
saveModalVisible.value = false;
|
||||
}
|
||||
|
|
|
@ -965,9 +965,15 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
const isReplace = ref(false);
|
||||
|
||||
function handleClose() {
|
||||
if (isReplace.value) {
|
||||
isReplace.value = false;
|
||||
} else {
|
||||
emit('applyStep', cloneDeep(makeRequestParams()) as RequestParam);
|
||||
}
|
||||
}
|
||||
|
||||
// const showAddDependencyDrawer = ref(false);
|
||||
// const addDependencyMode = ref<'pre' | 'post'>('pre');
|
||||
|
@ -1019,8 +1025,9 @@
|
|||
* @param newStep 替换的新步骤
|
||||
*/
|
||||
function handleReplace(newStep: ScenarioStepItem) {
|
||||
isReplace.value = true;
|
||||
emit('replace', {
|
||||
...newStep,
|
||||
...cloneDeep(newStep),
|
||||
name: activeStep.value?.name || newStep.name,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
block-node
|
||||
draggable
|
||||
hide-switcher
|
||||
@select="(selectedKeys, node) => handleStepSelect(selectedKeys, node as ScenarioStepItem)"
|
||||
@select="(selectedKeys, node) => handleStepSelect(node as ScenarioStepItem)"
|
||||
@expand="handleStepExpand"
|
||||
@more-actions-close="() => setFocusNodeKey('')"
|
||||
@more-action-select="handleStepMoreActionSelect"
|
||||
|
@ -1069,6 +1069,7 @@
|
|||
steps.value.splice(index, 1, newStep);
|
||||
}
|
||||
}
|
||||
activeStep.value = newStep;
|
||||
}
|
||||
Message.success(t('apiScenario.replaceSuccess'));
|
||||
scenario.value.unSaved = true;
|
||||
|
@ -1080,7 +1081,7 @@
|
|||
customApiDrawerVisible.value = false;
|
||||
nextTick(() => {
|
||||
// 等待抽屉关闭后再打开新的抽屉
|
||||
handleStepSelect([newStep.uniqueId], newStep);
|
||||
handleStepSelect(newStep);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,10 +81,10 @@ export default function useStepOperation({
|
|||
|
||||
/**
|
||||
* 处理步骤选中事件
|
||||
* @param _selectedKeys 选中的 key集合
|
||||
* @param step 点击的步骤节点
|
||||
*/
|
||||
async function handleStepSelect(_selectedKeys: Array<string | number>, step: ScenarioStepItem) {
|
||||
async function handleStepSelect(step: ScenarioStepItem) {
|
||||
activeStep.value = step;
|
||||
const _stepType = getStepType(step);
|
||||
const offspringIds: string[] = [];
|
||||
mapTree(step.children || [], (e) => {
|
||||
|
@ -94,7 +94,6 @@ export default function useStepOperation({
|
|||
selectedKeys.value = [step.uniqueId, ...offspringIds];
|
||||
if (_stepType.isCopyApi || _stepType.isQuoteApi || step.stepType === ScenarioStepType.CUSTOM_REQUEST) {
|
||||
// 复制 api、引用 api、自定义 api打开抽屉
|
||||
activeStep.value = step;
|
||||
if (
|
||||
step.isQuoteScenarioStep ||
|
||||
(stepDetails.value[step.id] === undefined && step.copyFromStepId) ||
|
||||
|
@ -106,7 +105,6 @@ export default function useStepOperation({
|
|||
}
|
||||
customApiDrawerVisible.value = true;
|
||||
} else if (step.stepType === ScenarioStepType.API_CASE) {
|
||||
activeStep.value = step;
|
||||
if (
|
||||
step.isQuoteScenarioStep ||
|
||||
(_stepType.isCopyCase && stepDetails.value[step.id] === undefined && step.copyFromStepId) ||
|
||||
|
@ -119,7 +117,6 @@ export default function useStepOperation({
|
|||
}
|
||||
customCaseDrawerVisible.value = true;
|
||||
} else if (step.stepType === ScenarioStepType.SCRIPT) {
|
||||
activeStep.value = step;
|
||||
if (
|
||||
step.isQuoteScenarioStep ||
|
||||
(stepDetails.value[step.id] === undefined && step.copyFromStepId) ||
|
||||
|
|
|
@ -242,6 +242,7 @@
|
|||
}
|
||||
};
|
||||
const handleCancel = (shouldSearch: boolean) => {
|
||||
formRef.value?.resetFields();
|
||||
emit('cancel', shouldSearch);
|
||||
};
|
||||
|
||||
|
|
|
@ -143,9 +143,10 @@
|
|||
try {
|
||||
const result = await getLicenseInfo();
|
||||
licenseInfo.value = result;
|
||||
licenseStore.setLicenseStatus(licenseInfo.value?.status);
|
||||
licenseStore.setLicenseInfo(licenseInfo.value);
|
||||
licenseStore.getExpirationTime(licenseInfo.value.license.expired);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
|
@ -174,6 +175,7 @@
|
|||
getLicenseDetail();
|
||||
cancelHandler();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
drawerLoading.value = false;
|
||||
|
|
Loading…
Reference in New Issue