fix(全局): 修改系统设置bug&用例管理需求bug调整
This commit is contained in:
parent
ff5421775d
commit
f065ec134e
|
@ -811,7 +811,7 @@
|
|||
}
|
||||
|
||||
/*** 徽标 ****/
|
||||
.arco-badge-number {
|
||||
.arco-badge-text {
|
||||
height: 16px !important;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
|
|
|
@ -215,6 +215,9 @@
|
|||
async (val) => {
|
||||
if (val) {
|
||||
personalMenus.value = [...copyPersonalMenus.value];
|
||||
if (appStore.packageType === 'enterprise') {
|
||||
getOrgList();
|
||||
}
|
||||
} else {
|
||||
personalMenus.value.splice(1, 1);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</div>
|
||||
|
||||
<icon-plus-circle-fill
|
||||
v-permission="['SYSTEM_USER_ROLE:READ+ADD']"
|
||||
v-permission="props.addPermission"
|
||||
class="cursor-pointer text-[rgb(var(--primary-7))]"
|
||||
size="20"
|
||||
@click="handleCreateUG(AuthScopeEnum.SYSTEM)"
|
||||
|
@ -72,7 +72,7 @@
|
|||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction
|
||||
v-if="element.type === systemType"
|
||||
v-permission="['SYSTEM_USER_ROLE:READ+UPDATE']"
|
||||
v-permission="props.updatePermission"
|
||||
:list="addMemberActionItem"
|
||||
@select="handleAddMember"
|
||||
>
|
||||
|
@ -81,6 +81,7 @@
|
|||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction
|
||||
v-if="isSystemShowAll"
|
||||
:list="systemMoreAction"
|
||||
@select="(value) => handleMoreAction(value, element.id, AuthScopeEnum.SYSTEM)"
|
||||
>
|
||||
|
@ -126,7 +127,7 @@
|
|||
</div>
|
||||
|
||||
<icon-plus-circle-fill
|
||||
v-permission="['ORGANIZATION_USER_ROLE:READ+ADD']"
|
||||
v-permission="props.addPermission"
|
||||
class="cursor-pointer text-[rgb(var(--primary-7))]"
|
||||
size="20"
|
||||
@click="orgUserGroupVisible = true"
|
||||
|
@ -159,7 +160,7 @@
|
|||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction
|
||||
v-if="element.type === systemType"
|
||||
v-permission="['ORGANIZATION_USER_ROLE:READ+UPDATE']"
|
||||
v-permission="props.updatePermission"
|
||||
:list="addMemberActionItem"
|
||||
@select="handleAddMember"
|
||||
>
|
||||
|
@ -168,7 +169,8 @@
|
|||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction
|
||||
v-permission="['ORGANIZATION_USER_ROLE:READ+UPDATE']"
|
||||
v-if="isOrdShowAll"
|
||||
v-permission="props.updatePermission"
|
||||
:list="orgMoreAction"
|
||||
@select="(value) => handleMoreAction(value, element.id, AuthScopeEnum.ORGANIZATION)"
|
||||
>
|
||||
|
@ -214,7 +216,7 @@
|
|||
</div>
|
||||
|
||||
<icon-plus-circle-fill
|
||||
v-permission="['PROJECT_GROUP:READ+ADD']"
|
||||
v-permission="props.addPermission"
|
||||
class="cursor-pointer text-[rgb(var(--primary-7))]"
|
||||
size="20"
|
||||
@click="projectUserGroupVisible = true"
|
||||
|
@ -247,15 +249,16 @@
|
|||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction
|
||||
v-if="element.type === systemType"
|
||||
v-permission="['PROJECT_GROUP:READ+UPDATE']"
|
||||
v-permission="props.updatePermission"
|
||||
:list="addMemberActionItem"
|
||||
@select="handleAddMember"
|
||||
>
|
||||
<div class="icon-button">
|
||||
<div v-permission="props.updatePermission" class="icon-button">
|
||||
<MsIcon type="icon-icon_add_outlined" size="16" />
|
||||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction
|
||||
v-if="isProjectShowAll"
|
||||
:list="projectMoreAction"
|
||||
@select="(value) => handleMoreAction(value, element.id, AuthScopeEnum.PROJECT)"
|
||||
>
|
||||
|
@ -306,6 +309,12 @@
|
|||
(e: 'handleSelect', element: UserGroupItem): void;
|
||||
(e: 'addUserSuccess', id: string): void;
|
||||
}>();
|
||||
|
||||
const props = defineProps<{
|
||||
addPermission: string[];
|
||||
updatePermission: string[];
|
||||
}>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const { openModal } = useModal();
|
||||
|
||||
|
@ -354,14 +363,16 @@
|
|||
return userGroupList.value.filter((ele) => ele.type === AuthScopeEnum.PROJECT);
|
||||
});
|
||||
|
||||
const addMemberActionItem: ActionsItem[] = [{ label: 'system.userGroup.addMember', eventTag: 'addMember' }];
|
||||
const addMemberActionItem: ActionsItem[] = [
|
||||
{ label: 'system.userGroup.addMember', eventTag: 'addMember', permission: props.updatePermission },
|
||||
];
|
||||
|
||||
const systemMoreAction: ActionsItem[] = [
|
||||
{
|
||||
label: 'system.userGroup.rename',
|
||||
danger: false,
|
||||
eventTag: 'rename',
|
||||
permission: ['SYSTEM_USER_ROLE:READ+UPDATE'],
|
||||
permission: props.updatePermission,
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
|
@ -378,7 +389,7 @@
|
|||
label: 'system.userGroup.rename',
|
||||
danger: false,
|
||||
eventTag: 'rename',
|
||||
permission: ['ORGANIZATION_USER_ROLE:READ+UPDATE'],
|
||||
permission: props.updatePermission,
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
|
@ -387,7 +398,7 @@
|
|||
label: 'system.userGroup.delete',
|
||||
danger: true,
|
||||
eventTag: 'delete',
|
||||
permission: ['ORGANIZATION_USER_ROLE:READ+UPDATE'],
|
||||
permission: ['ORGANIZATION_USER_ROLE:READ+DELETE'],
|
||||
},
|
||||
];
|
||||
const projectMoreAction: ActionsItem[] = [
|
||||
|
@ -395,7 +406,7 @@
|
|||
label: 'system.userGroup.rename',
|
||||
danger: false,
|
||||
eventTag: 'rename',
|
||||
permission: ['PROJECT_GROUP:READ+UPDATE'],
|
||||
permission: props.updatePermission,
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
|
@ -404,7 +415,7 @@
|
|||
label: 'system.userGroup.delete',
|
||||
danger: true,
|
||||
eventTag: 'delete',
|
||||
permission: ['PROJECT_GROUP:READ+UPDATE'],
|
||||
permission: ['PROJECT_GROUP:READ+DELETE'],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -550,6 +561,16 @@
|
|||
emit('addUserSuccess', currentId.value);
|
||||
}
|
||||
};
|
||||
|
||||
const isSystemShowAll = computed(() => {
|
||||
return hasAnyPermission([...props.updatePermission, 'SYSTEM_USER_ROLE:READ+DELETE']);
|
||||
});
|
||||
const isOrdShowAll = computed(() => {
|
||||
return hasAnyPermission([...props.updatePermission, 'ORGANIZATION_USER_ROLE:READ+DELETE']);
|
||||
});
|
||||
const isProjectShowAll = computed(() => {
|
||||
return hasAnyPermission([...props.updatePermission, 'PROJECT_GROUP:READ+DELETE']);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -272,6 +272,8 @@
|
|||
() => formRuleList.value,
|
||||
(val) => {
|
||||
if (val) emit('update:form-item', formRuleList.value);
|
||||
fApi.value.refreshValidate();
|
||||
fApi.value.clearValidateState();
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
|
@ -289,4 +291,13 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
:deep(.arco-form-item-status-success .arco-select-view:not(.arco-select-view-disabled).arco-select-view-focus) {
|
||||
border-color: var(--color-text-input-border);
|
||||
background: none;
|
||||
}
|
||||
:deep(.arco-form-item-status-success .arco-select-view:not(.arco-select-view-disabled)) {
|
||||
border-color: var(--color-text-input-border);
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -209,7 +209,7 @@ export default function useTableProps<T>(
|
|||
...loadListParams.value,
|
||||
};
|
||||
const data = await loadListFunc(tableQueryParams.value);
|
||||
const tmpArr = data.list;
|
||||
const tmpArr = data.list || data.data.list;
|
||||
propsRes.value.data = tmpArr.map((item: MsTableDataItem<T>) => {
|
||||
if (item.updateTime) {
|
||||
item.updateTime = dayjs(item.updateTime).format('YYYY-MM-DD HH:mm:ss');
|
||||
|
|
|
@ -21,6 +21,7 @@ export default {
|
|||
'menu.workbench': '工作台',
|
||||
'menu.testPlan': '测试计划',
|
||||
'menu.bugManagement': '缺陷管理',
|
||||
'menu.bugManagement.bugDetail': '缺陷管理',
|
||||
'menu.caseManagement': '用例管理',
|
||||
'menu.apiTest': '接口测试',
|
||||
'menu.apiTest.debug': '接口调试',
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { useRouter } from 'vue-router';
|
||||
import { defineStore } from 'pinia';
|
||||
import { Notification } from '@arco-design/web-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
@ -10,11 +11,13 @@ import { getPackageType, getSystemVersion } from '@/api/modules/system';
|
|||
import { getMenuList } from '@/api/modules/user';
|
||||
import defaultSettings from '@/config/settings.json';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { NO_PROJECT_ROUTE_NAME } from '@/router/constants';
|
||||
import { watchStyle, watchTheme } from '@/utils/theme';
|
||||
|
||||
import type { PageConfig, PageConfigKeys, Style, Theme } from '@/models/setting/config';
|
||||
import { ProjectListItem } from '@/models/setting/project';
|
||||
|
||||
import useUserStore from '../user';
|
||||
import type { AppState } from './types';
|
||||
import type { NotificationReturn } from '@arco-design/web-vue/es/notification/interface';
|
||||
import type { RouteRecordNormalized, RouteRecordRaw } from 'vue-router';
|
||||
|
@ -230,6 +233,8 @@ const useAppStore = defineStore('app', {
|
|||
async initSystemPackage() {
|
||||
try {
|
||||
this.packageType = await getPackageType();
|
||||
// await getPackageType();
|
||||
// this.packageType = 'community';
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
|
|
|
@ -14,6 +14,7 @@ const useFeatureCaseStore = defineStore('featureCase', {
|
|||
recycleModulesCount: Record<string, any>; // 回收站模块数量
|
||||
operatingState: boolean; // 操作状态
|
||||
tabSettingList: TabItemType[]; // 详情tab
|
||||
activeTab: string; // 激活tab
|
||||
} => ({
|
||||
moduleId: [],
|
||||
caseTree: [],
|
||||
|
@ -21,6 +22,7 @@ const useFeatureCaseStore = defineStore('featureCase', {
|
|||
recycleModulesCount: {},
|
||||
operatingState: false,
|
||||
tabSettingList: [],
|
||||
activeTab: 'detail',
|
||||
}),
|
||||
actions: {
|
||||
// 设置选择moduleId
|
||||
|
@ -65,6 +67,24 @@ const useFeatureCaseStore = defineStore('featureCase', {
|
|||
getTab() {
|
||||
return this.tabSettingList.filter((item) => item.enable);
|
||||
},
|
||||
// 设置激活tab
|
||||
setActiveTab(active: string | number) {
|
||||
this.activeTab = active as string;
|
||||
},
|
||||
// 设置菜单模块列表数量
|
||||
setListCount(type: string, count = 0) {
|
||||
this.tabSettingList = this.tabSettingList.map((item: any) => {
|
||||
if (type === item.key) {
|
||||
return {
|
||||
...item,
|
||||
total: count,
|
||||
};
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
};
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ import { defineStore } from 'pinia';
|
|||
|
||||
import { getLicenseInfo } from '@/api/modules/setting/authorizedManagement';
|
||||
|
||||
import useAppStore from '../app';
|
||||
|
||||
const useLicenseStore = defineStore('license', {
|
||||
persist: true,
|
||||
state: (): { status: string | null } => ({
|
||||
|
@ -19,12 +21,16 @@ const useLicenseStore = defineStore('license', {
|
|||
},
|
||||
// license校验
|
||||
async getValidateLicense() {
|
||||
const appStore = useAppStore();
|
||||
try {
|
||||
const result = await getLicenseInfo();
|
||||
if (!result || !result.status || !result.license || !result.license.count) {
|
||||
return;
|
||||
await appStore.initSystemPackage();
|
||||
if (appStore.packageType === 'enterprise') {
|
||||
const result = await getLicenseInfo();
|
||||
if (!result || !result.status || !result.license || !result.license.count) {
|
||||
return;
|
||||
}
|
||||
this.setLicenseStatus(result.status);
|
||||
}
|
||||
this.setLicenseStatus(result.status);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ const useTemplateStore = defineStore('template', {
|
|||
if (currentOrgId.value && hasAnyPermission(['ORGANIZATION_TEMPLATE:READ'])) {
|
||||
this.ordStatus = await getOrdTemplate(currentOrgId.value);
|
||||
}
|
||||
|
||||
if (currentProjectId.value && hasAnyPermission(['PROJECT_TEMPLATE:READ'])) {
|
||||
this.projectStatus = await getProTemplate(currentProjectId.value);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ const useUserStore = defineStore('user', {
|
|||
certification: undefined,
|
||||
role: '',
|
||||
userRolePermissions: [],
|
||||
loginType: [],
|
||||
}),
|
||||
|
||||
getters: {
|
||||
|
@ -100,7 +101,7 @@ const useUserStore = defineStore('user', {
|
|||
async getAuthentication() {
|
||||
try {
|
||||
const res = await getAuthenticationList();
|
||||
console.log(res);
|
||||
this.loginType = res;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
|
|
@ -40,4 +40,5 @@ export interface UserState {
|
|||
lastOrganizationId?: string;
|
||||
lastProjectId?: string;
|
||||
userRolePermissions?: UserRolePermissions[];
|
||||
loginType: string[];
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<template #caseStep="{ record }">
|
||||
<a-textarea
|
||||
v-if="record.showStep"
|
||||
:ref="(el: refItem) => setStepRefMap(el, record)"
|
||||
v-model="record.step"
|
||||
size="mini"
|
||||
:auto-size="true"
|
||||
|
@ -26,6 +27,7 @@
|
|||
<template #expectedResult="{ record }">
|
||||
<a-textarea
|
||||
v-if="record.showExpected"
|
||||
:ref="(el: refItem) => setExpectedRefMap(el, record)"
|
||||
v-model="record.expected"
|
||||
:max-length="1000"
|
||||
size="mini"
|
||||
|
@ -78,6 +80,7 @@
|
|||
import type { StepList } from '@/models/caseManagement/featureCase';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
type refItem = Element | ComponentPublicInstance | null;
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = withDefaults(
|
||||
|
@ -240,13 +243,32 @@
|
|||
});
|
||||
};
|
||||
|
||||
const refStepMap: Record<string, any> = {};
|
||||
function setStepRefMap(el: refItem, record: StepList) {
|
||||
if (el) {
|
||||
refStepMap[`${record.id}`] = el;
|
||||
}
|
||||
}
|
||||
const expectedRefMap: Record<string, any> = {};
|
||||
|
||||
function setExpectedRefMap(el: refItem, record: StepList) {
|
||||
if (el) {
|
||||
expectedRefMap[`${record.id}`] = el;
|
||||
}
|
||||
}
|
||||
// 编辑步骤
|
||||
function edit(record: StepList, type: string) {
|
||||
if (props.isDisabled) return;
|
||||
if (type === 'step') {
|
||||
record.showStep = true;
|
||||
nextTick(() => {
|
||||
refStepMap[record.id]?.focus();
|
||||
});
|
||||
} else {
|
||||
record.showExpected = true;
|
||||
nextTick(() => {
|
||||
expectedRefMap[record.id]?.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,6 +281,7 @@
|
|||
record.showExpected = false;
|
||||
}
|
||||
}
|
||||
|
||||
const tableRef = ref<InstanceType<typeof MsBaseTable> | null>(null);
|
||||
|
||||
watchEffect(() => {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
import { createCaseRequest, updateCaseRequest } from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useVisit from '@/hooks/useVisit';
|
||||
import { useAppStore } from '@/store';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import { scrollIntoView } from '@/utils/dom';
|
||||
|
||||
|
@ -50,6 +51,7 @@
|
|||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
|
||||
|
@ -61,6 +63,27 @@
|
|||
fileList: [],
|
||||
});
|
||||
|
||||
const initDetail = {
|
||||
id: '',
|
||||
templateId: '',
|
||||
name: '',
|
||||
prerequisite: '', // prerequisite
|
||||
caseEditType: 'STEP', // 编辑模式:步骤模式/文本模式
|
||||
steps: '',
|
||||
textDescription: '',
|
||||
expectedResult: '', // 预期结果
|
||||
description: '',
|
||||
publicCase: false, // 是否公共用例
|
||||
moduleId: '',
|
||||
versionId: '',
|
||||
tags: [],
|
||||
projectId: appStore.currentProjectId,
|
||||
customFields: {}, // 自定义字段集合
|
||||
relateFileMetaIds: [], // 关联文件ID集合
|
||||
deleteFileMetaIds: [], // 删除本地上传的文件id
|
||||
unLinkFilesIds: [], // 取消关联的文件id
|
||||
};
|
||||
|
||||
const title = ref('');
|
||||
const loading = ref(false);
|
||||
const isEdit = computed(() => !!route.query.id);
|
||||
|
@ -69,8 +92,8 @@
|
|||
const isContinueFlag = ref(false);
|
||||
const isShowTip = ref<boolean>(true);
|
||||
const createSuccessId = ref<string>('');
|
||||
|
||||
async function save(isReview: boolean) {
|
||||
const caseModuleDetailRef = ref();
|
||||
async function save(isReview: boolean, isContinue: boolean) {
|
||||
try {
|
||||
loading.value = true;
|
||||
// 编辑用例
|
||||
|
@ -88,6 +111,11 @@
|
|||
caseDetailInfo.value.request.reviewId = route.query.reviewId;
|
||||
}
|
||||
const res = await createCaseRequest(caseDetailInfo.value);
|
||||
if (isContinue) {
|
||||
Message.success(t('caseManagement.featureCase.addSuccess'));
|
||||
caseModuleDetailRef.value.resetForm();
|
||||
return;
|
||||
}
|
||||
createSuccessId.value = res.data.id;
|
||||
Message.success(route.params.mode === 'copy' ? t('ms.description.copySuccess') : t('common.addSuccess'));
|
||||
featureCaseStore.setIsAlreadySuccess(true);
|
||||
|
@ -122,8 +150,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
const caseModuleDetailRef = ref();
|
||||
|
||||
// 保存
|
||||
function saveHandler(isContinue = false, isReview = false) {
|
||||
const { caseFormRef, formRef, fApi } = caseModuleDetailRef.value;
|
||||
|
@ -134,7 +160,7 @@
|
|||
if (valid === true) {
|
||||
formRef?.validate().then((result: any) => {
|
||||
if (!result) {
|
||||
return save(isReview);
|
||||
return save(isReview, isContinue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
:width="1200"
|
||||
:footer="false"
|
||||
:mask="false"
|
||||
:title="t('caseManagement.featureCase.caseDetailTitle', { id: detailInfo?.id, name: detailInfo?.name })"
|
||||
:title="t('caseManagement.featureCase.caseDetailTitle', { id: detailInfo?.num, name: detailInfo?.name })"
|
||||
:detail-id="props.detailId"
|
||||
:detail-index="props.detailIndex"
|
||||
:get-detail-func="getCaseDetail"
|
||||
|
@ -104,7 +104,7 @@
|
|||
class="ml-1"
|
||||
:class="activeTab === tab.key ? 'active' : ''"
|
||||
:count="1000"
|
||||
:max-count="99"
|
||||
:text="getTotal(tab.total)"
|
||||
/> </div
|
||||
></a-menu-item>
|
||||
<a-menu-item key="setting">
|
||||
|
@ -173,7 +173,7 @@
|
|||
<!-- 自定义字段结束 -->
|
||||
<div class="baseItem">
|
||||
<span class="label"> {{ t('caseManagement.featureCase.tableColumnCreateUser') }}</span>
|
||||
<span>{{ detailInfo?.createUser }}</span>
|
||||
<span>{{ detailInfo?.createUserName }}</span>
|
||||
</div>
|
||||
<div class="baseItem">
|
||||
<span class="label"> {{ t('caseManagement.featureCase.tableColumnCreateTime') }}</span>
|
||||
|
@ -289,6 +289,7 @@
|
|||
const activeTab = ref<string | number>('detail');
|
||||
function clickMenu(key: string | number) {
|
||||
activeTab.value = key;
|
||||
featureCaseStore.setActiveTab(key);
|
||||
switch (activeTab.value) {
|
||||
case 'setting':
|
||||
activeTab.value = 'detail';
|
||||
|
@ -524,7 +525,10 @@
|
|||
event: noticeUserIds.value.join(';') ? 'AT' : 'COMMENT', // 任务事件(仅评论: ’COMMENT‘; 评论并@: ’AT‘; 回复评论/回复并@: ’REPLAY‘;)
|
||||
};
|
||||
await createCommentList(params);
|
||||
commentRef.value.getAllCommentList();
|
||||
if (activeTab.value === 'comments') {
|
||||
commentRef.value.getAllCommentList();
|
||||
}
|
||||
|
||||
Message.success(t('common.publishSuccessfully'));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
@ -539,6 +543,13 @@
|
|||
tabDetailRef.value.handleOK();
|
||||
}, 300);
|
||||
|
||||
function getTotal(total: number) {
|
||||
if (total <= 99) {
|
||||
return String(total);
|
||||
}
|
||||
return `${total}+`;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.detailId,
|
||||
(val) => {
|
||||
|
@ -601,7 +612,7 @@
|
|||
color: rgb(var(--danger-6));
|
||||
}
|
||||
}
|
||||
:deep(.active .arco-badge-number) {
|
||||
:deep(.active .arco-badge-text) {
|
||||
background: rgb(var(--primary-5));
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
<template>
|
||||
<!-- 用例表开始 -->
|
||||
<MsAdvanceFilter
|
||||
v-model:keyword="keyword"
|
||||
:filter-config-list="filterConfigList"
|
||||
:custom-fields-config-list="searchCustomFields"
|
||||
:row-count="filterRowCount"
|
||||
@keyword-search="fetchData"
|
||||
@adv-search="handleAdvSearch"
|
||||
@reset="fetchData"
|
||||
>
|
||||
<template #left>
|
||||
<div class="text-[var(--color-text-1)]"
|
||||
|
@ -34,10 +36,10 @@
|
|||
@change="changeHandler"
|
||||
>
|
||||
<template #num="{ record, rowIndex }">
|
||||
<span class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</span>
|
||||
<a-button type="text" class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</a-button>
|
||||
</template>
|
||||
<template #name="{ record, rowIndex }">
|
||||
<a-button type="text" class="px-0" @click="showCaseDetail(record.id, rowIndex)">{{ record.name }}</a-button>
|
||||
<span type="text" class="px-0" @click="showCaseDetail(record.id, rowIndex)">{{ record.name }}</span>
|
||||
</template>
|
||||
<template #caseLevel="{ record }">
|
||||
<caseLevel :case-level="getCaseLevels(record.customFields)" />
|
||||
|
@ -969,7 +971,6 @@
|
|||
|
||||
const fetchData = (keywordStr = '') => {
|
||||
setKeyword(keywordStr);
|
||||
keyword.value = keywordStr;
|
||||
getLoadListParams();
|
||||
loadList();
|
||||
};
|
||||
|
|
|
@ -579,16 +579,6 @@
|
|||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.caseId) {
|
||||
getCaseInfo();
|
||||
} else {
|
||||
initDefaultFields();
|
||||
}
|
||||
initSelectTree();
|
||||
});
|
||||
|
||||
// 处理关联文件和已关联文件本地文件和已上传文本文件
|
||||
function getFilesParams() {
|
||||
form.value.deleteFileMetaIds = deleteFileMetaIds.value;
|
||||
|
@ -756,10 +746,32 @@
|
|||
return data;
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
form.value = { ...initForm };
|
||||
fileList.value = [];
|
||||
caseFormRef.value?.resetFields();
|
||||
}
|
||||
|
||||
const caseId = ref(props.caseId);
|
||||
|
||||
watchEffect(() => {
|
||||
if (caseId.value) {
|
||||
getCaseInfo();
|
||||
} else {
|
||||
initDefaultFields();
|
||||
}
|
||||
initSelectTree();
|
||||
});
|
||||
|
||||
onBeforeMount(() => {
|
||||
caseId.value = '';
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
caseFormRef,
|
||||
formRef,
|
||||
fApi,
|
||||
resetForm,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
import { postTabletList } from '@/api/modules/project-management/menuManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
|
||||
import type { TableQueryParams } from '@/models/common';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
@ -91,6 +92,7 @@
|
|||
import Message from '@arco-design/web-vue/es/message';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -255,14 +257,16 @@
|
|||
currentSelectCase.value = caseTypeOptions.value[0].value;
|
||||
}
|
||||
|
||||
function getFetch() {
|
||||
async function getFetch() {
|
||||
setLoadListParams({
|
||||
keyword: keyword.value,
|
||||
sourceId: props.caseId,
|
||||
projectId: currentProjectId.value,
|
||||
sourceType: currentSelectCase.value,
|
||||
});
|
||||
loadList();
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
}
|
||||
|
||||
async function searchCase() {
|
||||
|
|
|
@ -40,12 +40,14 @@
|
|||
|
||||
import { getDetailCaseReviewPage } from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { getReviewStatusClass, getStatusText } from '../utils';
|
||||
import debounce from 'lodash-es/debounce';
|
||||
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps<{
|
||||
|
@ -101,24 +103,17 @@
|
|||
enableDrag: true,
|
||||
});
|
||||
|
||||
function initData() {
|
||||
async function initData() {
|
||||
setLoadListParams({ keyword: keyword.value, caseId: props.caseId });
|
||||
loadList();
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
}
|
||||
|
||||
const searchList = debounce(() => {
|
||||
initData();
|
||||
}, 100);
|
||||
|
||||
function getReviewStatus(status: string) {
|
||||
switch (status) {
|
||||
case 'UN_REVIEWED':
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
onBeforeMount(() => {
|
||||
initData();
|
||||
});
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useVisit from '@/hooks/useVisit';
|
||||
import { useAppStore } from '@/store';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
@ -90,7 +91,7 @@
|
|||
const { t } = useI18n();
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
const visitedKey = 'notRemindChangeHistoryTip';
|
||||
const { addVisited } = useVisit(visitedKey);
|
||||
const { getIsVisited } = useVisit(visitedKey);
|
||||
|
@ -216,13 +217,15 @@
|
|||
isShowTip.value = !getIsVisited();
|
||||
};
|
||||
|
||||
function initData() {
|
||||
async function initData() {
|
||||
setLoadListParams({
|
||||
projectId: appStore.currentProjectId,
|
||||
sourceId: props.caseId,
|
||||
module: 'FUNCTIONAL_CASE',
|
||||
});
|
||||
loadList();
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
|
|
|
@ -44,7 +44,9 @@
|
|||
} from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
const { openModal } = useModal();
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -76,15 +78,24 @@
|
|||
}
|
||||
}
|
||||
|
||||
function getAllCommentList() {
|
||||
function setCount(list: CommentItem[]) {
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, list.length);
|
||||
}
|
||||
|
||||
async function getAllCommentList() {
|
||||
switch (activeComment.value) {
|
||||
case 'caseComment':
|
||||
initCommentList();
|
||||
await initCommentList();
|
||||
setCount(commentList.value);
|
||||
break;
|
||||
case 'reviewComment':
|
||||
initReviewCommentList();
|
||||
await initCommentList();
|
||||
setCount(reviewCommentList.value);
|
||||
break;
|
||||
case 'executiveComment':
|
||||
await initCommentList();
|
||||
setCount(commentList.value);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -36,12 +36,13 @@
|
|||
import { getDemandList } from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
|
||||
import type { DemandItem } from '@/models/caseManagement/featureCase';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const pageConfig = computed(() => appStore.pageConfig);
|
||||
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = withDefaults(
|
||||
|
@ -109,7 +110,9 @@
|
|||
|
||||
const initData = async () => {
|
||||
setLoadListParams({ ...props.funParams });
|
||||
loadList();
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
<AddDemandModal v-model:visible="showAddModel" :case-id="props.caseId" :form="modelForm" @success="searchList()" />
|
||||
<MsDrawer
|
||||
v-model:visible="linkDemandDrawer"
|
||||
:ok-disabled="tableSelected.length < 1"
|
||||
:mask="false"
|
||||
:title="t('caseManagement.featureCase.associatedDemand')"
|
||||
:ok-text="t('caseManagement.featureCase.associated')"
|
||||
:ok-loading="drawerLoading"
|
||||
:ok-disabled="tableSelected.length < 1"
|
||||
:width="960"
|
||||
unmount-on-close
|
||||
:show-continue="false"
|
||||
|
@ -41,8 +41,8 @@
|
|||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div
|
||||
><span class="font-medium">XXXXXXXXX</span
|
||||
><span class="ml-1 text-[var(--color-text-4)]">({{ propsRes.value }})</span></div
|
||||
><span class="font-medium">{{ getPlatName() }}</span
|
||||
><span class="ml-1 text-[var(--color-text-4)]">({{ propsRes?.msPagination?.total || 0 }})</span></div
|
||||
>
|
||||
<a-input-search
|
||||
v-model="platformKeyword"
|
||||
|
@ -61,6 +61,9 @@
|
|||
<span>({{ (record.children || []).length || 0 }})</span></span
|
||||
>
|
||||
</template>
|
||||
<template v-for="item in customFields" :key="item.slotName" #[item.dataIndex]="{ record }">
|
||||
<span> {{ getSlotName(record, item) }} </span>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</MsDrawer>
|
||||
</div>
|
||||
|
@ -68,16 +71,18 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { debounce } from 'lodash-es';
|
||||
|
||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import type { MsTableColumn, MsTableColumnData } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import AddDemandModal from './addDemandModal.vue';
|
||||
import AssociatedDemandTable from './associatedDemandTable.vue';
|
||||
|
||||
import { batchAssociationDemand, getThirdDemandList } from '@/api/modules/case-management/featureCase';
|
||||
import { getCaseRelatedInfo } from '@/api/modules/project-management/menuManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
|
||||
|
@ -130,87 +135,49 @@
|
|||
title: 'caseManagement.featureCase.tableColumnID',
|
||||
slotName: 'demandId',
|
||||
dataIndex: 'demandId',
|
||||
showInTable: true,
|
||||
width: 200,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnName',
|
||||
slotName: 'demandName',
|
||||
dataIndex: 'demandName',
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.platformDemandState',
|
||||
width: 300,
|
||||
dataIndex: 'status',
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.platformDemandHandler',
|
||||
width: 300,
|
||||
dataIndex: 'handler',
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.IterationPlan',
|
||||
width: 300,
|
||||
dataIndex: 'iterationPlan',
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
ellipsis: true,
|
||||
},
|
||||
// {
|
||||
// title: 'caseManagement.featureCase.platformDemandState',
|
||||
// width: 300,
|
||||
// dataIndex: 'status',
|
||||
// showTooltip: true,
|
||||
// ellipsis: true,
|
||||
// },
|
||||
// {
|
||||
// title: 'caseManagement.featureCase.platformDemandHandler',
|
||||
// width: 300,
|
||||
// dataIndex: 'handler',
|
||||
// showTooltip: true,
|
||||
// ellipsis: true,
|
||||
// },
|
||||
];
|
||||
const fullColumns = ref<MsTableColumn>([]);
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getThirdDemandList, {
|
||||
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEMAND_PLATFORM,
|
||||
columns,
|
||||
rowKey: 'id',
|
||||
columns: fullColumns.value,
|
||||
rowKey: 'demandId',
|
||||
scroll: { x: '100%' },
|
||||
selectable: false,
|
||||
selectable: true,
|
||||
showSetting: false,
|
||||
});
|
||||
|
||||
const showDrawer = ref<boolean>(false);
|
||||
|
||||
const drawerLoading = ref<boolean>(false);
|
||||
|
||||
const tableSelected = computed(() => {
|
||||
const selectIds = [...propsRes.value.selectedKeys];
|
||||
return propsRes.value.data.filter((item: any) => selectIds.indexOf(item.id) > -1);
|
||||
return propsRes.value.data.filter((item: any) => selectIds.indexOf(item.demandId) > -1);
|
||||
});
|
||||
|
||||
async function handleDrawerConfirm() {
|
||||
const params = {
|
||||
id: '',
|
||||
caseId: props.caseId,
|
||||
demandPlatform: '',
|
||||
demandList: [
|
||||
{
|
||||
demandId: 'string',
|
||||
parent: 'string',
|
||||
demandName: 'string',
|
||||
demandUrl: 'string',
|
||||
},
|
||||
],
|
||||
};
|
||||
try {
|
||||
drawerLoading.value = true;
|
||||
await batchAssociationDemand(params);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
drawerLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDrawerCancel() {
|
||||
showDrawer.value = false;
|
||||
}
|
||||
|
||||
// 关联需求
|
||||
const linkDemandDrawer = ref<boolean>(false);
|
||||
function associatedDemand() {
|
||||
|
@ -229,19 +196,113 @@
|
|||
resetSelector();
|
||||
};
|
||||
|
||||
watch(
|
||||
() => linkDemandDrawer.value,
|
||||
(val) => {
|
||||
if (val) {
|
||||
resetSelector();
|
||||
initData();
|
||||
const tableRef = ref();
|
||||
const customFields = ref<any[]>([]);
|
||||
async function initColumn() {
|
||||
try {
|
||||
const res = await getThirdDemandList({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
projectId: currentProjectId.value,
|
||||
});
|
||||
customFields.value = (res.data.customHeaders || []).map((item: any) => {
|
||||
return {
|
||||
title: item.name,
|
||||
slotName: item.id,
|
||||
dataIndex: item.id,
|
||||
width: 200,
|
||||
options: item.options,
|
||||
};
|
||||
}) as any;
|
||||
fullColumns.value = [...columns, ...customFields.value];
|
||||
tableRef.value.initColumn(fullColumns.value);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function getSlotName(record: any, item: MsTableColumnData) {
|
||||
if (item?.options) {
|
||||
const currentRecord = {
|
||||
...record,
|
||||
...record.customFields,
|
||||
};
|
||||
const currentValue = currentRecord[item.dataIndex as string];
|
||||
const currentOptions = (JSON.parse(item.options) || []).find((it: any) => it.value === currentValue);
|
||||
if (currentOptions) {
|
||||
return currentOptions.text;
|
||||
}
|
||||
}
|
||||
return record.customFields[item.dataIndex as string] || '-';
|
||||
}
|
||||
|
||||
const platformInfo = ref<Record<string, any>>({});
|
||||
async function handleDrawerConfirm() {
|
||||
const demandList = tableSelected.value.map((item) => {
|
||||
return {
|
||||
demandId: item.demandId,
|
||||
parent: item.parent,
|
||||
demandName: item.demandName,
|
||||
demandUrl: item.demandUrl,
|
||||
};
|
||||
});
|
||||
|
||||
const params = {
|
||||
id: JSON.parse(platformInfo.value.demand_platform_config).zentaoId,
|
||||
caseId: props.caseId,
|
||||
demandPlatform: platformInfo.value.platform_key,
|
||||
demandList,
|
||||
};
|
||||
try {
|
||||
drawerLoading.value = true;
|
||||
await batchAssociationDemand(params);
|
||||
Message.success(t('caseManagement.featureCase.associatedSuccess'));
|
||||
linkDemandDrawer.value = false;
|
||||
demandRef.value.initData();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
drawerLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDrawerCancel() {
|
||||
linkDemandDrawer.value = false;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => linkDemandDrawer.value,
|
||||
async (val) => {
|
||||
if (val) {
|
||||
resetSelector();
|
||||
await initColumn();
|
||||
initData();
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
// onMounted(() => {
|
||||
// resetSelector();
|
||||
// initData();
|
||||
// });
|
||||
|
||||
onBeforeMount(async () => {
|
||||
try {
|
||||
const result = await getCaseRelatedInfo(currentProjectId.value);
|
||||
if (result && result.platform_key) {
|
||||
platformInfo.value = { ...result };
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
|
||||
function getPlatName() {
|
||||
switch (platformInfo.value.platform_key) {
|
||||
case 'zentao':
|
||||
return t('caseManagement.featureCase.zentao');
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
@ -75,8 +75,11 @@
|
|||
import { cancelPreOrPostCase, getDependOnCase } from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
const featureCaseStore = useFeatureCaseStore();
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
export type types = 'preposition' | 'postPosition';
|
||||
|
@ -145,21 +148,6 @@
|
|||
enableDrag: false,
|
||||
});
|
||||
|
||||
const cancelLoading = ref<boolean>(false);
|
||||
// 取消依赖
|
||||
async function cancelDependency(record: any) {
|
||||
cancelLoading.value = true;
|
||||
try {
|
||||
await cancelPreOrPostCase(record.id);
|
||||
Message.success(t('caseManagement.featureCase.cancelFollowSuccess'));
|
||||
loadList();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
cancelLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function getParams() {
|
||||
setLoadListParams({
|
||||
projectId: currentProjectId.value,
|
||||
|
@ -169,6 +157,28 @@
|
|||
});
|
||||
}
|
||||
|
||||
async function initData() {
|
||||
getParams();
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
}
|
||||
|
||||
const cancelLoading = ref<boolean>(false);
|
||||
// 取消依赖
|
||||
async function cancelDependency(record: any) {
|
||||
cancelLoading.value = true;
|
||||
try {
|
||||
await cancelPreOrPostCase(record.id);
|
||||
Message.success(t('caseManagement.featureCase.cancelFollowSuccess'));
|
||||
initData();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
cancelLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const showDrawer = ref<boolean>(false);
|
||||
const drawerRef = ref();
|
||||
// 添加前后置用例
|
||||
|
@ -176,22 +186,19 @@
|
|||
showDrawer.value = true;
|
||||
drawerRef.value.initModules();
|
||||
}
|
||||
|
||||
function successHandler() {
|
||||
loadList();
|
||||
initData();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => showType.value,
|
||||
() => {
|
||||
getParams();
|
||||
loadList();
|
||||
initData();
|
||||
}
|
||||
);
|
||||
|
||||
onBeforeMount(() => {
|
||||
getParams();
|
||||
loadList();
|
||||
initData();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -251,4 +251,5 @@ export default {
|
|||
'caseManagement.featureCase.associatedSuccess': 'Associated with success',
|
||||
'caseManagement.featureCase.defectSource': 'defect Source',
|
||||
'caseManagement.featureCase.sortSuccess': 'Sort successfully',
|
||||
'caseManagement.featureCase.zentao': 'zentao',
|
||||
};
|
||||
|
|
|
@ -246,4 +246,5 @@ export default {
|
|||
'caseManagement.featureCase.associatedSuccess': '关联成功',
|
||||
'caseManagement.featureCase.defectSource': '缺陷来源',
|
||||
'caseManagement.featureCase.sortSuccess': '排序成功',
|
||||
'caseManagement.featureCase.zentao': '禅道',
|
||||
};
|
||||
|
|
|
@ -10,18 +10,16 @@
|
|||
</div>
|
||||
|
||||
<div class="form mt-[32px] min-w-[416px]">
|
||||
<div class="mb-7 text-[18px] font-medium text-[rgb(var(--primary-5))]">LDAP登录</div>
|
||||
<div v-if="userInfo.authenticate === 'LOCAL'" class="mb-7 text-[18px] font-medium text-[rgb(var(--primary-5))]">{{
|
||||
t('login.form.accountLogin')
|
||||
}}</div>
|
||||
<div
|
||||
v-if="isShowLDAP && userInfo.authenticate !== 'LOCAL'"
|
||||
class="mb-7 text-[18px] font-medium text-[rgb(var(--primary-5))]"
|
||||
>{{ t('login.form.LDAPLogin') }}</div
|
||||
>
|
||||
<a-form ref="formRef" :model="userInfo" @submit="handleSubmit">
|
||||
<!-- TOTO 第一版本暂时只考虑普通登录 -->
|
||||
<!-- <a-form-item class="login-form-item" field="radio" hide-label>
|
||||
<a-radio-group v-model="userInfo.authenticate" type="button">
|
||||
<a-radio value="LOCAL">{{ t('login.form.normalLogin') }}</a-radio>
|
||||
<a-radio value="LDAP">LDAP</a-radio>
|
||||
<a-radio value="OAuth2">{{ t('login.form.oauth2Test') }}</a-radio>
|
||||
<a-radio value="OIDC 90">OIDC 90</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item> -->
|
||||
|
||||
<!-- TOTO 第一版本暂时只考虑普通登录&LDAP -->
|
||||
<a-form-item
|
||||
class="login-form-item"
|
||||
field="username"
|
||||
|
@ -53,7 +51,12 @@
|
|||
<span class="text-xs font-normal text-[var(--color-text-4)]">{{ t('login.form.modeLoginMethods') }}</span>
|
||||
</a-divider>
|
||||
<div class="flex items-center justify-center">
|
||||
<div class="loginType"> <svg-icon width="18px" height="18px" name="userLogin"></svg-icon></div>
|
||||
<div v-if="userInfo.authenticate !== 'LDAP' && isShowLDAP" class="loginType" @click="switchLoginType('LDAP')">
|
||||
<span class="type-text text-[10px]">LDAP</span>
|
||||
</div>
|
||||
<div v-if="userInfo.authenticate !== 'LOCAL'" class="loginType" @click="switchLoginType('LOCAL')">
|
||||
<svg-icon width="18px" height="18px" name="userLogin"></svg-icon
|
||||
></div>
|
||||
<div class="loginType">
|
||||
<span class="type-text text-[10px]">OIDC</span>
|
||||
</div>
|
||||
|
@ -68,7 +71,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
|
@ -113,12 +116,20 @@
|
|||
password: '',
|
||||
});
|
||||
|
||||
const userInfo = reactive({
|
||||
const userInfo = ref<{
|
||||
authenticate: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}>({
|
||||
authenticate: 'LOCAL',
|
||||
username: '',
|
||||
password: '',
|
||||
});
|
||||
|
||||
function switchLoginType(type: string) {
|
||||
userInfo.value.authenticate = type;
|
||||
}
|
||||
|
||||
const handleSubmit = async ({
|
||||
errors,
|
||||
values,
|
||||
|
@ -133,7 +144,7 @@
|
|||
await userStore.login({
|
||||
username: encrypted(values.username),
|
||||
password: encrypted(values.password),
|
||||
authenticate: values.authenticate,
|
||||
authenticate: userInfo.value.authenticate,
|
||||
} as LoginData);
|
||||
Message.success(t('login.form.login.success'));
|
||||
const { rememberPassword } = loginConfig.value;
|
||||
|
@ -161,14 +172,13 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
onMounted(async () => {
|
||||
// userStore.getAuthenticationList();
|
||||
// try {
|
||||
// const res = await getAuthenticationList();
|
||||
// console.log(res);
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// }
|
||||
|
||||
const isShowLDAP = computed(() => {
|
||||
return userStore.loginType.includes('LDAP');
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
userStore.getAuthentication();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -13,4 +13,6 @@ export default {
|
|||
'login.form.normalLogin': 'Normal login',
|
||||
'login.form.oauth2Test': 'OAuth2 Test',
|
||||
'login.form.modeLoginMethods': 'More',
|
||||
'login.form.accountLogin': 'Account login',
|
||||
'login.form.LDAPLogin': 'LDAP',
|
||||
};
|
||||
|
|
|
@ -13,4 +13,6 @@ export default {
|
|||
'login.form.normalLogin': '普通登录',
|
||||
'login.form.oauth2Test': 'OAuth2 测试',
|
||||
'login.form.modeLoginMethods': '更多登录方式',
|
||||
'login.form.accountLogin': '账号登录',
|
||||
'login.form.LDAPLogin': 'LDAP登录',
|
||||
};
|
||||
|
|
|
@ -55,12 +55,13 @@
|
|||
level: 2,
|
||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT,
|
||||
},
|
||||
{
|
||||
key: 'projectVersion',
|
||||
title: t('project.permission.projectVersion'),
|
||||
level: 2,
|
||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_VERSION,
|
||||
},
|
||||
// TODO 第一版不开启版本
|
||||
// {
|
||||
// key: 'projectVersion',
|
||||
// title: t('project.permission.projectVersion'),
|
||||
// level: 2,
|
||||
// name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_VERSION,
|
||||
// },
|
||||
{
|
||||
key: 'memberPermission',
|
||||
title: t('project.permission.memberPermission'),
|
||||
|
|
|
@ -154,7 +154,6 @@
|
|||
{ ...form, DEMAND_PLATFORM_CONFIG: JSON.stringify(formData) },
|
||||
currentProjectId.value
|
||||
);
|
||||
Message.success(t('common.createSuccess'));
|
||||
handleCancel(true);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
|
|
@ -383,7 +383,7 @@
|
|||
);
|
||||
|
||||
onMounted(() => {
|
||||
setBreadText();
|
||||
// setBreadText();
|
||||
getClassifyField();
|
||||
if (!isEdit.value) {
|
||||
selectData.value = totalTemplateField.value.filter((item) => item.internal);
|
||||
|
|
|
@ -156,10 +156,8 @@
|
|||
const result = await configScript(cuurentPluginId);
|
||||
formRules.value = [...result];
|
||||
if (type.value === 'edit') {
|
||||
// fApi.value.nextTick(() => {
|
||||
fApi.value.setValue({ ...formItem.value.configuration });
|
||||
fApi.value.refresh();
|
||||
// });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
</a-form-item>
|
||||
<!-- 日期和数值 -->
|
||||
<a-form-item
|
||||
v-if="showDateOrNumber"
|
||||
v-if="showDateOrNumber?.length"
|
||||
field="selectFormat"
|
||||
:label="
|
||||
fieldForm.type === 'NUMBER' ? t('system.orgTemplate.numberFormat') : t('system.orgTemplate.dateFormat')
|
||||
|
@ -180,8 +180,10 @@
|
|||
|
||||
// 是否展示日期或数值
|
||||
const showDateOrNumber = computed(() => {
|
||||
selectFormat.value = getFieldType(fieldForm.value.type)[0].value;
|
||||
if (fieldForm.value.type) return getFieldType(fieldForm.value.type);
|
||||
if (getFieldType(fieldForm.value.type)[0]) {
|
||||
selectFormat.value = getFieldType(fieldForm.value.type)[0]?.value;
|
||||
if (fieldForm.value.type) return getFieldType(fieldForm.value.type);
|
||||
}
|
||||
});
|
||||
|
||||
// 批量表单-1.仅选项情况
|
||||
|
|
|
@ -66,8 +66,10 @@ export function getFieldType(selectFieldType: FormItemType): { label: string; va
|
|||
switch (selectFieldType) {
|
||||
case 'DATE':
|
||||
return dateOptions;
|
||||
default:
|
||||
case 'NUMBER':
|
||||
return numberTypeOptions;
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@
|
|||
);
|
||||
|
||||
onMounted(() => {
|
||||
setBreadText();
|
||||
// setBreadText();
|
||||
getClassifyField();
|
||||
if (!isEdit.value) {
|
||||
selectData.value = totalTemplateField.value.filter((item) => item.internal);
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
<div class="card">
|
||||
<MsSplitBox v-model:width="leftWidth" @expand-change="handleCollapse">
|
||||
<template #first>
|
||||
<UserGroupLeft ref="ugLeftRef" @handle-select="handleSelect" @add-user-success="handleAddMember" />
|
||||
<UserGroupLeft
|
||||
ref="ugLeftRef"
|
||||
:add-permission="['ORGANIZATION_USER_ROLE:READ+ADD']"
|
||||
:update-permission="['ORGANIZATION_USER_ROLE:READ+UPDATE']"
|
||||
@handle-select="handleSelect"
|
||||
@add-user-success="handleAddMember"
|
||||
/>
|
||||
</template>
|
||||
<template #second>
|
||||
<div class="p-[24px]">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</div>
|
||||
<a-radio-group v-model:model-value="activeType" type="button">
|
||||
<a-radio value="log">{{ t('system.config.memoryCleanup.log') }}</a-radio>
|
||||
<a-radio v-xpack value="history">{{ t('system.config.memoryCleanup.history') }}</a-radio>
|
||||
<a-radio value="history">{{ t('system.config.memoryCleanup.history') }}</a-radio>
|
||||
</a-radio-group>
|
||||
<template v-if="activeType === 'log'">
|
||||
<div class="mb-[8px] mt-[16px] flex items-center">
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
<template #title>
|
||||
<span v-if="isEdit">
|
||||
{{ t('system.organization.updateOrganization') }}
|
||||
<span class="text-[var(--color-text-4)]">({{ props.currentOrganization?.name }})</span>
|
||||
<a-tooltip :content="props.currentOrganization?.name" position="right">
|
||||
<span class="font-normal text-[var(--color-text-4)]"
|
||||
>({{ characterLimit(props.currentOrganization?.name) }})</span
|
||||
>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ t('system.organization.createOrganization') }}
|
||||
|
@ -69,6 +73,7 @@
|
|||
|
||||
import { createOrUpdateOrg } from '@/api/modules/setting/organizationAndProject';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
import { CreateOrUpdateSystemOrgParams } from '@/models/setting/system/orgAndProject';
|
||||
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
<div class="card">
|
||||
<MsSplitBox v-model:width="leftWidth" @expand-change="handleCollapse">
|
||||
<template #first>
|
||||
<UserGroupLeft ref="ugLeftRef" @handle-select="handleSelect" @add-user-success="handleAddMember" />
|
||||
<UserGroupLeft
|
||||
ref="ugLeftRef"
|
||||
:add-permission="['SYSTEM_USER_ROLE:READ+ADD']"
|
||||
:update-permission="['SYSTEM_USER_ROLE:READ+UPDATE']"
|
||||
@handle-select="handleSelect"
|
||||
@add-user-success="handleAddMember"
|
||||
/>
|
||||
</template>
|
||||
<template #second>
|
||||
<div class="p-[24px]">
|
||||
|
|
Loading…
Reference in New Issue