fix(系统管理&用例管理): 修复用例bug和补充权限和系统包类型补充

This commit is contained in:
xinxin.wu 2024-01-29 15:08:55 +08:00 committed by 刘瑞斌
parent eaf7160ee5
commit 15fc7e84ae
30 changed files with 314 additions and 181 deletions

View File

@ -52,8 +52,12 @@
onBeforeMount(async () => { onBeforeMount(async () => {
try { try {
appStore.initSystemVersion(); // await appStore.initSystemPackage(); //
licenseStore.getValidateLicense(); // license await appStore.initSystemVersion(); //
// license
if (appStore.packageType === 'enterprise') {
licenseStore.getValidateLicense();
}
if (licenseStore.hasLicense()) { if (licenseStore.hasLicense()) {
appStore.initPageConfig(); // appStore.initPageConfig(); //
} }

View File

@ -41,6 +41,7 @@ import {
GetCaseListUrl, GetCaseListUrl,
GetCaseModulesCountUrl, GetCaseModulesCountUrl,
GetCaseModuleTreeUrl, GetCaseModuleTreeUrl,
getChangeHistoryListUrl,
GetCommentListUrl, GetCommentListUrl,
GetDebugDrawerPageUrl, GetDebugDrawerPageUrl,
GetDefaultTemplateFieldsUrl, GetDefaultTemplateFieldsUrl,
@ -54,6 +55,7 @@ import {
GetReviewCommentListUrl, GetReviewCommentListUrl,
GetReviewerListUrl, GetReviewerListUrl,
GetSearchCustomFieldsUrl, GetSearchCustomFieldsUrl,
GetThirdDemandUrl,
getTransferTreeUrl, getTransferTreeUrl,
GetTrashCaseModuleTreeUrl, GetTrashCaseModuleTreeUrl,
importExcelCaseUrl, importExcelCaseUrl,
@ -79,6 +81,7 @@ import type {
BatchMoveOrCopyType, BatchMoveOrCopyType,
CaseManagementTable, CaseManagementTable,
CaseModuleQueryParams, CaseModuleQueryParams,
ChangeHistoryItem,
CreateOrUpdateDemand, CreateOrUpdateDemand,
CreateOrUpdateModule, CreateOrUpdateModule,
DeleteCaseType, DeleteCaseType,
@ -230,6 +233,11 @@ export function cancelAssociationDemand(id: string) {
return MSR.get({ url: `${CancelAssociationDemandUrl}/${id}` }); return MSR.get({ url: `${CancelAssociationDemandUrl}/${id}` });
} }
// 获取三方关联需求列表
export function getThirdDemandList(data: TableQueryParams) {
return MSR.post({ url: GetThirdDemandUrl, data });
}
// 附件 // 附件
// 上传文件并关联用例 // 上传文件并关联用例
@ -408,4 +416,9 @@ export function dragSort(data: DragCase) {
return MSR.post({ url: dragSortUrl, data }); return MSR.post({ url: dragSortUrl, data });
} }
// 获取已关联缺陷列表
export function getChangeHistoryList(data: TableQueryParams) {
return MSR.post<CommonList<ChangeHistoryItem>>({ url: getChangeHistoryListUrl, data });
}
export default {}; export default {};

View File

@ -1,6 +1,6 @@
// 系统全局类的接口 // 系统全局类的接口
import MSR from '@/api/http/index'; import MSR from '@/api/http/index';
import { GetVersionUrl, OrgOptionsUrl, SwitchOrgUrl } from '@/api/requrls/system'; import { GetVersionUrl, OrgOptionsUrl, PackageTypeUrl, SwitchOrgUrl } from '@/api/requrls/system';
// 获取系统版本 // 获取系统版本
export function getSystemVersion() { export function getSystemVersion() {
@ -16,3 +16,8 @@ export function getOrgOptions() {
export function switchUserOrg(organizationId: string, userId: string) { export function switchUserOrg(organizationId: string, userId: string) {
return MSR.post({ url: SwitchOrgUrl, data: { organizationId, userId } }, { ignoreCancelToken: true }); return MSR.post({ url: SwitchOrgUrl, data: { organizationId, userId } }, { ignoreCancelToken: true });
} }
// 获取当前系统的版本
export function getPackageType() {
return MSR.get<'community' | 'enterprise'>({ url: PackageTypeUrl }, { ignoreCancelToken: true });
}

View File

@ -71,6 +71,8 @@ export const UpdateDemandUrl = '/functional/case/demand/update';
export const BatchAssociationDemandUrl = '/functional/case/demand/batch/relevance'; export const BatchAssociationDemandUrl = '/functional/case/demand/batch/relevance';
// 取消关联 // 取消关联
export const CancelAssociationDemandUrl = '/functional/case/demand/cancel'; export const CancelAssociationDemandUrl = '/functional/case/demand/cancel';
// 获取三方关联需求的接口
export const GetThirdDemandUrl = '/functional/case/demand/third/list/page';
// 附件管理 // 附件管理
// 上传文件并关联用例 // 上传文件并关联用例
@ -145,3 +147,5 @@ export const exportExcelCheckUrl = '/functional/case/pre-check/excel';
export const importExcelCaseUrl = '/functional/case/import/excel'; export const importExcelCaseUrl = '/functional/case/import/excel';
// 用例拖拽排序 // 用例拖拽排序
export const dragSortUrl = '/functional/case/edit/pos'; export const dragSortUrl = '/functional/case/edit/pos';
// 获取变更历史
export const getChangeHistoryListUrl = '/functional/case/operation-history';

View File

@ -3,3 +3,4 @@
export const GetVersionUrl = '/system/version/current'; export const GetVersionUrl = '/system/version/current';
export const OrgOptionsUrl = '/system/organization/switch-option'; export const OrgOptionsUrl = '/system/organization/switch-option';
export const SwitchOrgUrl = '/system/organization/switch'; export const SwitchOrgUrl = '/system/organization/switch';
export const PackageTypeUrl = '/system/version/package-type';

View File

@ -89,7 +89,7 @@
?.filter((item: any) => permission.accessRouter(item) && item.meta?.isTopMenu) ?.filter((item: any) => permission.accessRouter(item) && item.meta?.isTopMenu)
.filter((item: any) => { .filter((item: any) => {
if (item.name === RouteEnum.SETTING_SYSTEM_AUTHORIZED_MANAGEMENT) { if (item.name === RouteEnum.SETTING_SYSTEM_AUTHORIZED_MANAGEMENT) {
return licenseStore.hasLicense(); return appStore.packageType === 'enterprise';
} }
return true; return true;
}); });

View File

@ -12,6 +12,7 @@
:span-all="props.spanAll" :span-all="props.spanAll"
@expand="(rowKey, record) => emit('expand', record)" @expand="(rowKey, record) => emit('expand', record)"
@sorter-change="(dataIndex: string,direction: string) => handleSortChange(dataIndex, direction)" @sorter-change="(dataIndex: string,direction: string) => handleSortChange(dataIndex, direction)"
@cell-click="(record: TableData,column: TableColumnData,ev: Event) => emit('cell-click',record, column,ev)"
> >
<template #optional="{ rowIndex, record }"> <template #optional="{ rowIndex, record }">
<slot name="optional" v-bind="{ rowIndex, record }" /> <slot name="optional" v-bind="{ rowIndex, record }" />
@ -59,6 +60,7 @@
:summary-cell-style="item.summaryCellStyle" :summary-cell-style="item.summaryCellStyle"
:index="item.index" :index="item.index"
:tooltip="item.tooltip" :tooltip="item.tooltip"
:title="item.slotName"
> >
<template #title> <template #title>
<div :class="{ 'flex w-full flex-row flex-nowrap items-center': !item.align }"> <div :class="{ 'flex w-full flex-row flex-nowrap items-center': !item.align }">
@ -255,7 +257,7 @@
MsTableColumn, MsTableColumn,
MsTableProps, MsTableProps,
} from './type'; } from './type';
import type { TableData } from '@arco-design/web-vue'; import type { TableColumnData, TableData } from '@arco-design/web-vue';
const batchLeft = ref('10px'); const batchLeft = ref('10px');
const { t } = useI18n(); const { t } = useI18n();
@ -290,6 +292,7 @@
(e: 'selectAllChange', value: SelectAllEnum): void; (e: 'selectAllChange', value: SelectAllEnum): void;
(e: 'sorterChange', value: { [key: string]: string }): void; (e: 'sorterChange', value: { [key: string]: string }): void;
(e: 'expand', record: TableData): void | Promise<any>; (e: 'expand', record: TableData): void | Promise<any>;
(e: 'cell-click', record: TableData, column: TableColumnData, ev: Event): void | Promise<any>;
(e: 'clearSelector'): void; (e: 'clearSelector'): void;
(e: 'filterChange', dataIndex: string, value: (string | number)[], multiple: boolean, isCustomParam: boolean): void; (e: 'filterChange', dataIndex: string, value: (string | number)[], multiple: boolean, isCustomParam: boolean): void;
}>(); }>();

View File

@ -33,6 +33,7 @@ export enum TableKeyEnum {
PROJECT_MANAGEMENT_COMMON_SCRIPT_CHANGE_HISTORY = 'projectManagementCommonScriptChangeHistory', PROJECT_MANAGEMENT_COMMON_SCRIPT_CHANGE_HISTORY = 'projectManagementCommonScriptChangeHistory',
ORGANIZATION_TEMPLATE_DEFECT_TABLE = 'organizationTemplateManagementDefect', ORGANIZATION_TEMPLATE_DEFECT_TABLE = 'organizationTemplateManagementDefect',
CASE_MANAGEMENT_TABLE = 'caseManagement', CASE_MANAGEMENT_TABLE = 'caseManagement',
CASE_MANAGEMENT_RECYCLE_TABLE = 'caseRecycleManagement',
CASE_MANAGEMENT_DETAIL_TABLE = 'caseManagementDetailTable', CASE_MANAGEMENT_DETAIL_TABLE = 'caseManagementDetailTable',
CASE_MANAGEMENT_ASSOCIATED_TABLE = 'caseManagementAssociatedFileTable', CASE_MANAGEMENT_ASSOCIATED_TABLE = 'caseManagementAssociatedFileTable',
BUG_MANAGEMENT = 'bugManagement', BUG_MANAGEMENT = 'bugManagement',

View File

@ -331,3 +331,16 @@ export interface DragCase {
moveMode: 'BEFORE' | 'AFTER' | 'APPEND'[]; // 拖拽类型 moveMode: 'BEFORE' | 'AFTER' | 'APPEND'[]; // 拖拽类型
moveId: string; moveId: string;
} }
// 变更历史
export interface ChangeHistoryItem {
id: string;
projectId: string;
createTime: string;
createUser: string;
sourceId: string;
type: string;
module: string;
refId: string;
createUserName: string;
versionName: string;
}

View File

@ -6,7 +6,7 @@ import type { BreadcrumbItem } from '@/components/business/ms-breadcrumb/types';
import { getProjectInfo } from '@/api/modules/project-management/basicInfo'; import { getProjectInfo } from '@/api/modules/project-management/basicInfo';
import { getPageConfig } from '@/api/modules/setting/config'; import { getPageConfig } from '@/api/modules/setting/config';
import { getSystemVersion } from '@/api/modules/system'; import { getPackageType, getSystemVersion } from '@/api/modules/system';
import { getMenuList } from '@/api/modules/user'; import { getMenuList } from '@/api/modules/user';
import defaultSettings from '@/config/settings.json'; import defaultSettings from '@/config/settings.json';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
@ -58,6 +58,7 @@ const useAppStore = defineStore('app', {
...defaultLoginConfig, ...defaultLoginConfig,
...defaultPlatformConfig, ...defaultPlatformConfig,
}, },
packageType: 'community',
}), }),
getters: { getters: {
@ -210,6 +211,16 @@ const useAppStore = defineStore('app', {
console.log(error); console.log(error);
} }
}, },
/**
*
*/
async initSystemPackage() {
try {
this.packageType = await getPackageType();
} catch (error) {
console.log(error);
}
},
/** /**
* *
*/ */

View File

@ -37,6 +37,7 @@ export interface AppState {
pageConfig: PageConfig; pageConfig: PageConfig;
innerHeight: number; innerHeight: number;
currentMenuConfig: string[]; currentMenuConfig: string[];
packageType: 'community' | 'enterprise';
} }
export interface UploadFileTaskState { export interface UploadFileTaskState {

View File

@ -83,6 +83,12 @@ const useUserStore = defineStore('user', {
appStore.setCurrentOrgId(res.lastOrganizationId || ''); appStore.setCurrentOrgId(res.lastOrganizationId || '');
appStore.setCurrentProjectId(res.lastProjectId || ''); appStore.setCurrentProjectId(res.lastProjectId || '');
this.setInfo(res); this.setInfo(res);
// 登录后初始化系统包版本
appStore.initSystemPackage();
if (appStore.packageType === 'enterprise') {
const licenseStore = useLicenseStore();
licenseStore.getValidateLicense();
}
} catch (err) { } catch (err) {
clearToken(); clearToken();
throw err; throw err;

View File

@ -73,6 +73,7 @@
async function save(isReview: boolean) { async function save(isReview: boolean) {
try { try {
loading.value = true; loading.value = true;
//
if (route.params.mode === 'edit') { if (route.params.mode === 'edit') {
await updateCaseRequest(caseDetailInfo.value); await updateCaseRequest(caseDetailInfo.value);
Message.success(t('caseManagement.featureCase.editSuccess')); Message.success(t('caseManagement.featureCase.editSuccess'));
@ -80,7 +81,9 @@
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE,
query: { organizationId: route.query.organizationId, projectId: route.query.projectId }, query: { organizationId: route.query.organizationId, projectId: route.query.projectId },
}); });
//
} else { } else {
//
if (isReview) { if (isReview) {
caseDetailInfo.value.request.reviewId = route.query.reviewId; caseDetailInfo.value.request.reviewId = route.query.reviewId;
} }
@ -89,6 +92,10 @@
Message.success(route.params.mode === 'copy' ? t('ms.description.copySuccess') : t('common.addSuccess')); Message.success(route.params.mode === 'copy' ? t('ms.description.copySuccess') : t('common.addSuccess'));
featureCaseStore.setIsAlreadySuccess(true); featureCaseStore.setIsAlreadySuccess(true);
isShowTip.value = !getIsVisited(); isShowTip.value = !getIsVisited();
if (isReview) {
router.back();
return;
}
if (isShowTip.value && !route.query.id) { if (isShowTip.value && !route.query.id) {
router.push({ router.push({
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_CREATE_SUCCESS, name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_CREATE_SUCCESS,
@ -97,25 +104,16 @@
...route.query, ...route.query,
}, },
}); });
} else {
router.push({
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE,
query: {
organizationId: route.query.organizationId,
projectId: route.query.projectId,
},
});
} }
} }
if (isReview) {
router.back();
return;
}
router.push({ name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, query: { ...route.query } });
featureCaseStore.setIsAlreadySuccess(true);
isShowTip.value = !getIsVisited();
if (isShowTip.value && !route.query.id) {
router.push({
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_CREATE_SUCCESS,
query: {
id: createSuccessId.value,
...route.query,
},
});
}
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(error); console.log(error);

View File

@ -124,7 +124,7 @@
<TabCaseReview v-else-if="activeTab === 'caseReview'" :case-id="props.detailId" /> <TabCaseReview v-else-if="activeTab === 'caseReview'" :case-id="props.detailId" />
<TabTestPlan v-else-if="activeTab === 'testPlan'" /> <TabTestPlan v-else-if="activeTab === 'testPlan'" />
<TabComment v-else-if="activeTab === 'comments'" ref="commentRef" :case-id="props.detailId" /> <TabComment v-else-if="activeTab === 'comments'" ref="commentRef" :case-id="props.detailId" />
<TabChangeHistory v-else-if="activeTab === 'changeHistory'" /> <TabChangeHistory v-else-if="activeTab === 'changeHistory'" :case-id="props.detailId" />
</div> </div>
</div> </div>
</template> </template>
@ -520,7 +520,7 @@
event: notifiers ? 'AT' : 'COMMENT', // (: COMMENT; @: AT; /@: REPLAY;) event: notifiers ? 'AT' : 'COMMENT', // (: COMMENT; @: AT; /@: REPLAY;)
}; };
await createCommentList(params); await createCommentList(params);
commentRef.value.initCommentList(); commentRef.value.getAllCommentList();
Message.success(t('common.publishSuccessfully')); Message.success(t('common.publishSuccessfully'));
} catch (error) { } catch (error) {
console.log(error); console.log(error);

View File

@ -32,6 +32,7 @@
v-on="propsEvent" v-on="propsEvent"
@batch-action="handleTableBatch" @batch-action="handleTableBatch"
@change="changeHandler" @change="changeHandler"
@cell-click="showCaseDetailEvent"
> >
<template #num="{ record, rowIndex }"> <template #num="{ record, rowIndex }">
<span class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</span> <span class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</span>
@ -84,8 +85,13 @@
</template> </template>
<!-- 渲染自定义字段开始TODO --> <!-- 渲染自定义字段开始TODO -->
<template v-for="item in customFieldsColumns" :key="item.slotName" #[item.slotName]="{ record }"> <template v-for="item in customFieldsColumns" :key="item.slotName" #[item.slotName]="{ record }">
<a-tooltip :content="getTableFields(record.customFields, item)" position="top" :mouse-enter-delay="100" mini> <a-tooltip
<div>{{ getTableFields(record.customFields, item) }}</div> :content="getTableFields(record.customFields, item as MsTableColumn)"
position="top"
:mouse-enter-delay="100"
mini
>
<div>{{ getTableFields(record.customFields, item as MsTableColumn) }}</div>
</a-tooltip> </a-tooltip>
</template> </template>
<!-- 渲染自定义字段结束 --> <!-- 渲染自定义字段结束 -->
@ -194,7 +200,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { Message, TableChangeExtra, TableData } from '@arco-design/web-vue'; import { Message, TableChangeExtra, TableColumnData, TableData } from '@arco-design/web-vue';
import { CustomTypeMaps, MsAdvanceFilter } from '@/components/pure/ms-advance-filter'; import { CustomTypeMaps, MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
import { FilterFormItem, FilterResult, FilterType } from '@/components/pure/ms-advance-filter/type'; import { FilterFormItem, FilterResult, FilterType } from '@/components/pure/ms-advance-filter/type';
@ -396,8 +402,8 @@
}, },
{ {
title: 'caseManagement.featureCase.tableColumnVersion', title: 'caseManagement.featureCase.tableColumnVersion',
slotName: 'versionId', slotName: 'versionName',
dataIndex: 'versionId', dataIndex: 'versionNam',
width: 300, width: 300,
showTooltip: true, showTooltip: true,
showInTable: true, showInTable: true,
@ -419,6 +425,18 @@
isTag: true, isTag: true,
showDrag: true, showDrag: true,
}, },
{
title: 'caseManagement.featureCase.tableColumnUpdateUser',
slotName: 'updateUserName',
dataIndex: 'updateUserName',
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
showInTable: true,
width: 200,
showDrag: true,
},
{ {
title: 'caseManagement.featureCase.tableColumnUpdateTime', title: 'caseManagement.featureCase.tableColumnUpdateTime',
slotName: 'updateTime', slotName: 'updateTime',
@ -433,8 +451,8 @@
}, },
{ {
title: 'caseManagement.featureCase.tableColumnCreateUser', title: 'caseManagement.featureCase.tableColumnCreateUser',
slotName: 'createUser', slotName: 'createUserName',
dataIndex: 'createUser', dataIndex: 'createUserName',
showInTable: true, showInTable: true,
width: 200, width: 200,
showDrag: true, showDrag: true,
@ -1121,21 +1139,24 @@
// //
async function changeHandler(data: TableData[], extra: TableChangeExtra, currentData: TableData[]) { async function changeHandler(data: TableData[], extra: TableChangeExtra, currentData: TableData[]) {
if (currentData.length === 1) {
return;
}
if (extra && extra.dragTarget?.id) { if (extra && extra.dragTarget?.id) {
const params: DragCase = { const params: DragCase = {
projectId: currentProjectId.value, projectId: currentProjectId.value,
targetId: '', targetId: '', // id
moveMode: 'BEFORE', moveMode: 'BEFORE',
moveId: extra.dragTarget.id as string, moveId: extra.dragTarget.id as string, // id
}; };
const index = currentData.findIndex((item: any) => item.raw.id === extra.dragTarget?.id); const index = currentData.findIndex((item: any) => item.key === extra.dragTarget?.id);
if (index > -1 && currentData[index + 1].raw) { if (index > -1 && currentData[index + 1]) {
params.moveMode = 'AFTER'; params.moveMode = 'BEFORE';
params.targetId = currentData[index + 1].raw.id; params.targetId = currentData[index + 1].raw.id;
} else if (index > -1 && !currentData[index + 1].raw) { } else if (index > -1 && !currentData[index + 1]) {
if (index > -1 && currentData[index - 1].raw) { if (index > -1 && currentData[index - 1]) {
params.moveMode = 'BEFORE'; params.moveMode = 'AFTER';
params.targetId = currentData[index - 1].raw.id; params.targetId = currentData[index - 1].raw.id;
} }
} }
@ -1149,7 +1170,13 @@
} }
} }
onBeforeMount(() => { function showCaseDetailEvent(record: TableData, column: TableColumnData, ev: Event) {
if (column.title === 'name' || column.title === 'num') {
const rowIndex = propsRes.value.data.map((item: any) => item.id).indexOf(record.id);
showCaseDetail(record.id, rowIndex);
}
}
onMounted(() => {
if (route.query.id) { if (route.query.id) {
showCaseDetail(route.query.id as string, 0); showCaseDetail(route.query.id as string, 0);
} }

View File

@ -84,6 +84,9 @@
v-on="propsEvent" v-on="propsEvent"
@batch-action="handleTableBatch" @batch-action="handleTableBatch"
> >
<template #num="{ record }">
<span class="flex w-full">{{ record.num }}</span>
</template>
<template #caseLevel="{ record }"> <template #caseLevel="{ record }">
<caseLevel :case-level="(getCaseLevels(record.customFields) as CaseLevel)" /> <caseLevel :case-level="(getCaseLevels(record.customFields) as CaseLevel)" />
</template> </template>
@ -108,21 +111,17 @@
<span class="one-line-text inline-block">{{ getModules(record.moduleId) }}</span> <span class="one-line-text inline-block">{{ getModules(record.moduleId) }}</span>
</a-tooltip> </a-tooltip>
</template> </template>
<!-- 自定义字段非系统TODO --> <!-- 回收站自定义字段 -->
<!-- <template v-for="item in customFieldsColumns" :key="item.slotName" #[item.slotName]="{ record }"> <template v-for="item in customFieldsColumns" :key="item.slotName" #[item.slotName]="{ record }">
<div v-if="isCaseLevel(item.slotName as string).name === '用例等级'" class="flex items-center"> <a-tooltip
<span v-if="!record.visible" class="flex items-center" @click="record.visible = true"> :content="getTableFields(record.customFields, item as MsTableColumn)"
<caseLevel :case-level="getCaseLevel(record, item)" /> position="top"
</span> :mouse-enter-delay="100"
</div> mini
<div v-if="isCaseLevel(item.slotName as string).name === '用例状态'" class="flex items-center"> >
<MsTag <div>{{ getTableFields(record.customFields, item as MsTableColumn) }}</div>
:type="getCaseState(record[item.slotName as string]).type" </a-tooltip>
:theme="getCaseState(record[item.slotName as string]).theme" </template>
>{{ record[item.slotName as string] }}</MsTag
>
</div>
</template> -->
<template #operation="{ record }"> <template #operation="{ record }">
<MsButton v-permission="['FUNCTIONAL_CASE:READ+DELETE']" @click="recoverCase(record.id)">{{ <MsButton v-permission="['FUNCTIONAL_CASE:READ+DELETE']" @click="recoverCase(record.id)">{{
t('caseManagement.featureCase.batchRecover') t('caseManagement.featureCase.batchRecover')
@ -154,12 +153,7 @@
import MsIcon from '@/components/pure/ms-icon-font/index.vue'; import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import MsSplitBox from '@/components/pure/ms-split-box/index.vue'; import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue'; import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import type { import type { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
BatchActionParams,
BatchActionQueryParams,
MsTableColumn,
MsTableColumnData,
} from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable'; import useTable from '@/components/pure/ms-table/useTable';
import type { TagType, Theme } from '@/components/pure/ms-tag/ms-tag.vue'; import type { TagType, Theme } from '@/components/pure/ms-tag/ms-tag.vue';
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue'; import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
@ -193,7 +187,7 @@
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/projectManagement/file';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
import { getCaseLevels, getReviewStatusClass, getStatusText } from './utils'; import { getCaseLevels, getReviewStatusClass, getStatusText, getTableFields } from './utils';
const tableStore = useTableStore(); const tableStore = useTableStore();
const featureCaseStore = useFeatureCaseStore(); const featureCaseStore = useFeatureCaseStore();
@ -211,7 +205,7 @@
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setAdvanceFilter } = useTable( const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setAdvanceFilter } = useTable(
getRecycleListRequest, getRecycleListRequest,
{ {
tableKey: TableKeyEnum.FILE_MANAGEMENT_CASE_RECYCLE, tableKey: TableKeyEnum.CASE_MANAGEMENT_RECYCLE_TABLE,
scroll: { x: scrollWidth.value }, scroll: { x: scrollWidth.value },
selectable: true, selectable: true,
showSetting: true, showSetting: true,
@ -228,20 +222,21 @@
}), }),
}) })
); );
const columns: MsTableColumn = [ const columns: MsTableColumn = [
{ {
title: 'caseManagement.featureCase.tableColumnID', 'title': 'caseManagement.featureCase.tableColumnID',
dataIndex: 'id', 'slotName': 'num',
width: 200, 'dataIndex': 'num',
showInTable: true, 'width': 200,
sortable: { 'showInTable': true,
'sortable': {
sortDirections: ['ascend', 'descend'], sortDirections: ['ascend', 'descend'],
sorter: true, sorter: true,
}, },
showTooltip: true, 'filter-icon-align-left': true,
ellipsis: true, 'showTooltip': true,
showDrag: false, 'ellipsis': true,
'showDrag': false,
}, },
{ {
title: 'caseManagement.featureCase.tableColumnName', title: 'caseManagement.featureCase.tableColumnName',
@ -264,15 +259,6 @@
width: 200, width: 200,
showDrag: true, showDrag: true,
}, },
{
title: 'caseManagement.featureCase.tableColumnCaseState',
dataIndex: 'caseState',
showInTable: true,
width: 200,
showTooltip: true,
ellipsis: true,
showDrag: true,
},
{ {
title: 'caseManagement.featureCase.tableColumnReviewResult', title: 'caseManagement.featureCase.tableColumnReviewResult',
dataIndex: 'reviewStatus', dataIndex: 'reviewStatus',
@ -291,8 +277,8 @@
}, },
{ {
title: 'caseManagement.featureCase.tableColumnVersion', title: 'caseManagement.featureCase.tableColumnVersion',
slotName: 'versionId', slotName: 'versionName',
dataIndex: 'versionId', dataIndex: 'versionNam',
width: 300, width: 300,
showTooltip: true, showTooltip: true,
showInTable: true, showInTable: true,
@ -301,6 +287,7 @@
{ {
title: 'caseManagement.featureCase.tableColumnModule', title: 'caseManagement.featureCase.tableColumnModule',
slotName: 'moduleId', slotName: 'moduleId',
dataIndex: 'moduleId',
showInTable: true, showInTable: true,
width: 300, width: 300,
showDrag: true, showDrag: true,
@ -314,28 +301,13 @@
showDrag: true, showDrag: true,
}, },
{ {
title: 'caseManagement.featureCase.tableColumnCreateUser', title: 'caseManagement.featureCase.tableColumnUpdateUser',
slotName: 'createUser', slotName: 'updateUserName',
dataIndex: 'createUser', dataIndex: 'updateUserName',
showInTable: true,
showDrag: true,
},
{
title: 'caseManagement.featureCase.tableColumnCreateTime',
slotName: 'createTime',
dataIndex: 'createTime',
showInTable: true,
sortable: { sortable: {
sortDirections: ['ascend', 'descend'], sortDirections: ['ascend', 'descend'],
sorter: true, sorter: true,
}, },
width: 200,
showDrag: true,
},
{
title: 'caseManagement.featureCase.tableColumnUpdateUser',
slotName: 'updateUser',
dataIndex: 'updateUser',
showInTable: true, showInTable: true,
width: 200, width: 200,
showDrag: true, showDrag: true,
@ -352,12 +324,31 @@
width: 200, width: 200,
showDrag: true, showDrag: true,
}, },
{
title: 'caseManagement.featureCase.tableColumnCreateUser',
slotName: 'createUserName',
dataIndex: 'createUserName',
showInTable: true,
width: 200,
showDrag: true,
},
{
title: 'caseManagement.featureCase.tableColumnCreateTime',
slotName: 'createTime',
dataIndex: 'createTime',
showInTable: true,
sortable: {
sortDirections: ['ascend', 'descend'],
},
width: 200,
showDrag: true,
},
{ {
title: 'caseManagement.featureCase.tableColumnActions', title: 'caseManagement.featureCase.tableColumnActions',
slotName: 'operation', slotName: 'operation',
dataIndex: 'operation', dataIndex: 'operation',
fixed: 'right', fixed: 'right',
width: 140, width: 260,
showInTable: true, showInTable: true,
showDrag: false, showDrag: false,
}, },
@ -668,13 +659,12 @@
// //
async function getDefaultFields() { async function getDefaultFields() {
const result = await getCaseDefaultFields(currentProjectId.value); const result = await getCaseDefaultFields(currentProjectId.value);
initDefaultFields.value = result.customFields; initDefaultFields.value = result.customFields.filter((item: any) => !item.internal);
customFieldsColumns = initDefaultFields.value.map((item: any) => { customFieldsColumns = initDefaultFields.value.map((item: any) => {
return { return {
title: item.fieldName, title: item.fieldName,
slotName: item.fieldId as string, slotName: item.fieldId as string,
dataIndex: item.fieldId, dataIndex: item.fieldId,
showTooltip: true,
showInTable: true, showInTable: true,
showDrag: true, showDrag: true,
width: 300, width: 300,
@ -686,7 +676,7 @@
...customFieldsColumns, ...customFieldsColumns,
...columns.slice(columns.length - 1, columns.length), ...columns.slice(columns.length - 1, columns.length),
]; ];
tableStore.initColumn(TableKeyEnum.CASE_MANAGEMENT_TABLE, fullColumns, 'drawer'); tableStore.initColumn(TableKeyEnum.CASE_MANAGEMENT_RECYCLE_TABLE, fullColumns, 'drawer');
tableRef.value?.initColumn(fullColumns); tableRef.value?.initColumn(fullColumns);
} }
@ -737,7 +727,7 @@
}, },
{ {
title: 'caseManagement.featureCase.tableColumnUpdateUser', title: 'caseManagement.featureCase.tableColumnUpdateUser',
dataIndex: 'updateUser', dataIndex: 'updateUserName',
type: FilterType.SELECT, type: FilterType.SELECT,
selectProps: { selectProps: {
mode: 'static', mode: 'static',
@ -826,7 +816,7 @@
getRecycleModules(); getRecycleModules();
initRecycleModulesCount(); initRecycleModulesCount();
}); });
tableStore.initColumn(TableKeyEnum.FILE_MANAGEMENT_CASE_RECYCLE, columns, 'drawer'); tableStore.initColumn(TableKeyEnum.CASE_MANAGEMENT_RECYCLE_TABLE, columns, 'drawer');
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

View File

@ -89,17 +89,17 @@
enable: true, enable: true,
}, },
], ],
testPlan: [ // testPlan: [
{ // {
key: 'testPlan', // key: 'testPlan',
title: 'caseManagement.featureCase.testPlan', // title: 'caseManagement.featureCase.testPlan',
enable: true, // enable: true,
}, // },
], // ],
}); });
let buggerTab: TabItemType[] = []; let buggerTab: TabItemType[] = [];
let testPlanTab: TabItemType[] = []; // let testPlanTab: TabItemType[] = [];
function getTabList() { function getTabList() {
if (licenseStore.hasLicense()) { if (licenseStore.hasLicense()) {
@ -134,25 +134,29 @@
title: 'caseManagement.featureCase.comments', title: 'caseManagement.featureCase.comments',
enable: true, enable: true,
}, },
...getTabList(), // TOTO Xpack
// ...getTabList(),
]); ]);
async function getTabModule() { async function getTabModule() {
buggerTab = []; buggerTab = [];
testPlanTab = []; // testPlanTab = [];
const result = await postTabletList({ projectId: currentProjectId.value }); const result = await postTabletList({ projectId: currentProjectId.value });
const enableModuleArr = result.filter((item: any) => item.module === 'testPlan' || item.module === 'bugManagement'); // TODO
// const enableModuleArr = result.filter((item: any) => item.module === 'testPlan' || item.module === 'bugManagement');
const enableModuleArr = result.filter((item: any) => item.module === 'bugManagement');
enableModuleArr.forEach((item) => { enableModuleArr.forEach((item) => {
if (item.module === 'bugManagement') { if (item.module === 'bugManagement') {
buggerTab.push(...moduleTab.value[item.module]); buggerTab.push(...moduleTab.value[item.module]);
} else if (item.module === 'testPlan') {
testPlanTab.push(...moduleTab.value[item.module]);
} }
// else if (item.module === 'testPlan') {
// testPlanTab.push(...moduleTab.value[item.module]);
// }
}); });
const newTabDefaultSettingList = [ const newTabDefaultSettingList = [
tabDefaultSettingList.value[0], tabDefaultSettingList.value[0],
...buggerTab, ...buggerTab,
...tabDefaultSettingList.value.slice(1, -2), ...tabDefaultSettingList.value.slice(1, -2),
...testPlanTab, // ...testPlanTab,
tabDefaultSettingList.value[tabDefaultSettingList.value.length - 2], tabDefaultSettingList.value[tabDefaultSettingList.value.length - 2],
tabDefaultSettingList.value[tabDefaultSettingList.value.length - 1], tabDefaultSettingList.value[tabDefaultSettingList.value.length - 1],
]; ];

View File

@ -21,9 +21,9 @@
<a-radio value="link" class="show-type-icon p-[2px]">{{ <a-radio value="link" class="show-type-icon p-[2px]">{{
t('caseManagement.featureCase.directLink') t('caseManagement.featureCase.directLink')
}}</a-radio> }}</a-radio>
<a-radio value="testPlan" class="show-type-icon p-[2px]">{{ <!-- <a-radio value="testPlan" class="show-type-icon p-[2px]">{{
t('caseManagement.featureCase.testPlan') t('caseManagement.featureCase.testPlan')
}}</a-radio> }}</a-radio> -->
</a-radio-group> </a-radio-group>
<a-input-search <a-input-search
v-model:model-value="keyword" v-model:model-value="keyword"
@ -135,7 +135,7 @@
const columns: MsTableColumn = [ const columns: MsTableColumn = [
{ {
title: 'caseManagement.featureCase.tableColumnID', title: 'caseManagement.featureCase.tableColumnID',
dataIndex: 'id', dataIndex: 'num',
width: 200, width: 200,
showInTable: true, showInTable: true,
showTooltip: true, showTooltip: true,

View File

@ -57,7 +57,7 @@
const columns: MsTableColumn = [ const columns: MsTableColumn = [
{ {
title: 'ID', title: 'ID',
dataIndex: 'reviewId', dataIndex: 'reviewNum',
sortIndex: 1, sortIndex: 1,
showTooltip: true, showTooltip: true,
width: 300, width: 300,

View File

@ -12,6 +12,7 @@
<template #name="{ record }"> <template #name="{ record }">
<a-button type="text" class="px-0">{{ record.name }}</a-button> <a-button type="text" class="px-0">{{ record.name }}</a-button>
</template> </template>
<template #type> </template>
<template #operation="{ record }"> <template #operation="{ record }">
<MsRemoveButton <MsRemoveButton
position="br" position="br"
@ -78,37 +79,43 @@
import MsFormItemSub from '@/components/business/ms-form-item-sub/index.vue'; import MsFormItemSub from '@/components/business/ms-form-item-sub/index.vue';
import MsRemoveButton from '@/components/business/ms-remove-button/MsRemoveButton.vue'; import MsRemoveButton from '@/components/business/ms-remove-button/MsRemoveButton.vue';
import { getRecycleListRequest } from '@/api/modules/case-management/featureCase'; import { getChangeHistoryList } from '@/api/modules/case-management/featureCase';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import useVisit from '@/hooks/useVisit'; import useVisit from '@/hooks/useVisit';
import { useAppStore } from '@/store';
import { characterLimit } from '@/utils'; import { characterLimit } from '@/utils';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
const { t } = useI18n(); const { t } = useI18n();
const appStore = useAppStore();
const visitedKey = 'notRemindChangeHistoryTip'; const visitedKey = 'notRemindChangeHistoryTip';
const { addVisited } = useVisit(visitedKey); const { addVisited } = useVisit(visitedKey);
const { getIsVisited } = useVisit(visitedKey); const { getIsVisited } = useVisit(visitedKey);
const props = defineProps<{
caseId: string;
}>();
const columns: MsTableColumn = [ const columns: MsTableColumn = [
{ {
title: 'caseManagement.featureCase.changeNumber', title: 'caseManagement.featureCase.changeNumber',
dataIndex: 'changeNumber', dataIndex: 'id',
showTooltip: true, showTooltip: true,
width: 90, width: 90,
}, },
{ {
title: 'caseManagement.featureCase.changeType', title: 'caseManagement.featureCase.changeType',
slotName: 'changeType', slotName: 'type',
dataIndex: 'changeType', dataIndex: 'type',
width: 200, width: 200,
}, },
{ {
title: 'caseManagement.featureCase.operator', title: 'caseManagement.featureCase.operator',
dataIndex: 'operator', dataIndex: 'createUser',
slotName: 'operator', slotName: 'createUser',
width: 150, width: 150,
}, },
{ {
@ -128,7 +135,7 @@
}, },
]; ];
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getRecycleListRequest, { const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getChangeHistoryList, {
columns, columns,
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_CHANGE_HISTORY, tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_CHANGE_HISTORY,
scroll: { x: '100%' }, scroll: { x: '100%' },
@ -209,8 +216,18 @@
isShowTip.value = !getIsVisited(); isShowTip.value = !getIsVisited();
}; };
function initData() {
setLoadListParams({
projectId: appStore.currentProjectId,
sourceId: props.caseId,
module: 'FUNCTIONAL_CASE',
});
loadList();
}
onBeforeMount(() => { onBeforeMount(() => {
doCheckIsTip(); doCheckIsTip();
initData();
}); });
</script> </script>

View File

@ -15,7 +15,7 @@
}}</MsButton> }}</MsButton>
</template> </template>
<template v-if="(props.funParams.keyword || '').trim() === ''" #empty> <template v-if="(props.funParams.keyword || '').trim() === ''" #empty>
<div class="flex w-full w-full items-center justify-center"> <div class="flex w-full items-center justify-center">
{{ t('caseManagement.caseReview.tableNoData') }} {{ t('caseManagement.caseReview.tableNoData') }}
<MsButton class="ml-[8px]" @click="emit('create')"> <MsButton class="ml-[8px]" @click="emit('create')">
{{ t('caseManagement.featureCase.addDemand') }} {{ t('caseManagement.featureCase.addDemand') }}
@ -49,6 +49,7 @@
funParams: { funParams: {
caseId: string; caseId: string;
keyword: string; keyword: string;
projectId: string;
}; // }; //
isShowOperation?: boolean; // isShowOperation?: boolean; //
highlightName?: boolean; // highlightName?: boolean; //
@ -106,8 +107,7 @@
}); });
const initData = async () => { const initData = async () => {
const { keyword, caseId } = props.funParams; setLoadListParams({ ...props.funParams });
setLoadListParams({ keyword, caseId });
loadList(); loadList();
}; };

View File

@ -21,7 +21,7 @@
</div> </div>
<AssociatedDemandTable <AssociatedDemandTable
ref="demandRef" ref="demandRef"
:fun-params="{ caseId: props.caseId, keyword }" :fun-params="{ caseId: props.caseId, keyword, projectId: currentProjectId }"
@update="updateDemand" @update="updateDemand"
@create="addDemand" @create="addDemand"
></AssociatedDemandTable> ></AssociatedDemandTable>
@ -29,7 +29,7 @@
<MsDrawer <MsDrawer
v-model:visible="linkDemandDrawer" v-model:visible="linkDemandDrawer"
:mask="false" :mask="false"
:title="t('caseManagement.featureCase.associatedFile')" :title="t('caseManagement.featureCase.associatedDemand')"
:ok-text="t('caseManagement.featureCase.associated')" :ok-text="t('caseManagement.featureCase.associated')"
:ok-loading="drawerLoading" :ok-loading="drawerLoading"
:ok-disabled="tableSelected.length < 1" :ok-disabled="tableSelected.length < 1"
@ -40,7 +40,10 @@
@cancel="handleDrawerCancel" @cancel="handleDrawerCancel"
> >
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div><span class="font-medium">XXXXXXXXX</span><span class="ml-1 text-[var(--color-text-4)]">(101)</span></div> <div
><span class="font-medium">XXXXXXXXX</span
><span class="ml-1 text-[var(--color-text-4)]">({{ propsRes.value }})</span></div
>
<a-input-search <a-input-search
v-model="platformKeyword" v-model="platformKeyword"
:max-length="250" :max-length="250"
@ -74,7 +77,7 @@
import AddDemandModal from './addDemandModal.vue'; import AddDemandModal from './addDemandModal.vue';
import AssociatedDemandTable from './associatedDemandTable.vue'; import AssociatedDemandTable from './associatedDemandTable.vue';
import { batchAssociationDemand, getDemandList } from '@/api/modules/case-management/featureCase'; import { batchAssociationDemand, getThirdDemandList } from '@/api/modules/case-management/featureCase';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store'; import { useAppStore } from '@/store';
@ -84,6 +87,8 @@
const { t } = useI18n(); const { t } = useI18n();
const appStore = useAppStore(); const appStore = useAppStore();
const currentProjectId = computed(() => appStore.currentProjectId);
const props = defineProps<{ const props = defineProps<{
caseId: string; caseId: string;
}>(); }>();
@ -160,7 +165,7 @@
}, },
]; ];
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getDemandList, { const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getThirdDemandList, {
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEMAND_PLATFORM, tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEMAND_PLATFORM,
columns, columns,
rowKey: 'id', rowKey: 'id',
@ -206,7 +211,7 @@
showDrawer.value = false; showDrawer.value = false;
} }
// () //
const linkDemandDrawer = ref<boolean>(false); const linkDemandDrawer = ref<boolean>(false);
function associatedDemand() { function associatedDemand() {
linkDemandDrawer.value = true; linkDemandDrawer.value = true;
@ -215,8 +220,8 @@
const platformKeyword = ref<string>(''); const platformKeyword = ref<string>('');
const initData = async () => { const initData = async () => {
setLoadListParams({ keyword: platformKeyword.value }); setLoadListParams({ keyword: platformKeyword.value, projectId: currentProjectId.value });
// loadList(); loadList();
}; };
const searchHandler = () => { const searchHandler = () => {
@ -224,10 +229,19 @@
resetSelector(); resetSelector();
}; };
onMounted(() => { watch(
resetSelector(); () => linkDemandDrawer.value,
initData(); (val) => {
}); if (val) {
resetSelector();
initData();
}
}
);
// onMounted(() => {
// resetSelector();
// initData();
// });
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -250,7 +250,7 @@
const columns: MsTableColumn = [ const columns: MsTableColumn = [
{ {
title: 'ID', title: 'ID',
dataIndex: 'id', dataIndex: 'num',
sortIndex: 1, sortIndex: 1,
showTooltip: true, showTooltip: true,
sortable: { sortable: {

View File

@ -1,3 +1,4 @@
import { MsTableColumnData } from '@/components/pure/ms-table/type';
import type { MsFileItem } from '@/components/pure/ms-upload/types'; import type { MsFileItem } from '@/components/pure/ms-upload/types';
import type { CaseLevel } from '@/components/business/ms-case-associate/types'; import type { CaseLevel } from '@/components/business/ms-case-associate/types';
@ -133,30 +134,35 @@ export function getCaseLevels(customFields: CustomAttributes[]): CaseLevel {
} }
// 处理自定义字段 // 处理自定义字段
export function getTableFields(customFields: any, itemDataIndex: any) { export function getTableFields(customFields: CustomAttributes[], itemDataIndex: MsTableColumnData) {
const multipleExcludes = ['MULTIPLE_SELECT', 'CHECKBOX', 'MULTIPLE_MEMBER']; const multipleExcludes = ['MULTIPLE_SELECT', 'CHECKBOX', 'MULTIPLE_MEMBER'];
const selectExcludes = ['MEMBER', 'RADIO', 'SELECT']; const selectExcludes = ['MEMBER', 'RADIO', 'SELECT'];
const currentColumnData = customFields.find((item: any) => itemDataIndex.dataIndex === item.fieldId); const currentColumnData: CustomAttributes | undefined = customFields.find(
// 处理多选项 (item: any) => itemDataIndex.dataIndex === item.fieldId
if (multipleExcludes.includes(currentColumnData.type)) { );
const selectValue = JSON.parse(currentColumnData.defaultValue);
return currentColumnData.options if (currentColumnData) {
.filter((item: any) => selectValue.includes(item.value)) // 处理多选项
.map((it: any) => it.text) if (multipleExcludes.includes(currentColumnData.type)) {
.join(','); const selectValue = JSON.parse(currentColumnData.defaultValue);
return currentColumnData.options
.filter((item: any) => selectValue.includes(item.value))
.map((it: any) => it.text)
.join(',');
}
if (currentColumnData.type === 'MULTIPLE_INPUT') {
// 处理标签形式
return JSON.parse(currentColumnData.defaultValue).join('');
}
if (selectExcludes.includes(currentColumnData.type)) {
return currentColumnData.options
.filter((item: any) => currentColumnData.defaultValue === item.value)
.map((it: any) => it.text)
.join();
}
return currentColumnData.defaultValue;
} }
if (currentColumnData.type === 'MULTIPLE_INPUT') {
// 处理标签形式
return JSON.parse(currentColumnData.defaultValue).join('');
}
if (selectExcludes.includes(currentColumnData.type)) {
return currentColumnData.options
.filter((item: any) => currentColumnData.defaultValue === item.value)
.map((it: any) => it.text)
.join();
}
return currentColumnData.defaultValue;
} }
export default {}; export default {};

View File

@ -219,7 +219,7 @@
</div> </div>
<caseTabDemand <caseTabDemand
ref="caseDemandRef" ref="caseDemandRef"
:fun-params="{ caseId: route.query.caseId as string, keyword: demandKeyword }" :fun-params="{ caseId: route.query.caseId as string, keyword: demandKeyword,projectId:appStore.currentProjectId }"
/> />
</div> </div>
</div> </div>

View File

@ -8,16 +8,17 @@
<span class="title-welcome">{{ innerSlogan || t('login.form.title') }}</span> <span class="title-welcome">{{ innerSlogan || t('login.form.title') }}</span>
</div> </div>
</div> </div>
<div class="form mt-[32px]"> <div class="form mt-[32px] min-w-[416px]">
<a-form ref="formRef" :model="userInfo" @submit="handleSubmit"> <a-form ref="formRef" :model="userInfo" @submit="handleSubmit">
<a-form-item class="login-form-item" field="radio" hide-label> <!-- TOTO 第一版本暂时只考虑普通登录 -->
<!-- <a-form-item class="login-form-item" field="radio" hide-label>
<a-radio-group v-model="userInfo.authenticate" type="button"> <a-radio-group v-model="userInfo.authenticate" type="button">
<a-radio value="LOCAL">普通登陆</a-radio> <a-radio value="LOCAL">普通登陆</a-radio>
<a-radio v-xpack value="LDAP">LDAP</a-radio> <a-radio v-xpack value="LDAP">LDAP</a-radio>
<a-radio value="OAuth2">OAuth2 测试</a-radio> <a-radio v-xpack value="OAuth2">OAuth2 测试</a-radio>
<a-radio value="OIDC 90">OIDC 90</a-radio> <a-radio v-xpack value="OIDC 90">OIDC 90</a-radio>
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item> -->
<a-form-item <a-form-item
class="login-form-item" class="login-form-item"
field="username" field="username"

View File

@ -26,7 +26,11 @@
<span class="font-normal">{{ t(item.title) }}</span> <span class="font-normal">{{ t(item.title) }}</span>
<span> <span>
<a-tooltip <a-tooltip
:content="isHasSystemPermission ? '' : t('organization.service.noPermissionsTip')" :content="
isHasSystemPermission
? t('organization.service.jumpPlugin')
: t('organization.service.noPermissionsTip')
"
position="bottom" position="bottom"
> >
<a-button <a-button

View File

@ -20,7 +20,7 @@
<a-input-number <a-input-number
v-model:model-value="timeCount" v-model:model-value="timeCount"
class="w-[130px]" class="w-[130px]"
:disabled="saveLoading" :disabled="saveLoading || !userStore.isAdmin"
@blur="() => saveConfig()" @blur="() => saveConfig()"
> >
<template #append> <template #append>
@ -61,7 +61,9 @@
import { getCleanupConfig, saveCleanupConfig } from '@/api/modules/setting/config'; import { getCleanupConfig, saveCleanupConfig } from '@/api/modules/setting/config';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useUserStore } from '@/store';
const userStore = useUserStore();
const { t } = useI18n(); const { t } = useI18n();
const loading = ref(false); const loading = ref(false);

View File

@ -113,10 +113,15 @@
<MsButton v-permission="['SYSTEM_PLUGIN:READ+UPDATE']" @click="update(record)">{{ <MsButton v-permission="['SYSTEM_PLUGIN:READ+UPDATE']" @click="update(record)">{{
t('system.plugin.edit') t('system.plugin.edit')
}}</MsButton> }}</MsButton>
<MsButton v-if="record.enable" @click="disableHandler(record)">{{ <MsButton
t('system.plugin.tableDisable') v-if="record.enable"
v-permission="['SYSTEM_PLUGIN:READ+UPDATE']"
@click="disableHandler(record)"
>{{ t('system.plugin.tableDisable') }}</MsButton
>
<MsButton v-else v-permission="['SYSTEM_PLUGIN:READ+UPDATE']" @click="enableHandler(record)">{{
t('system.plugin.tableEnable')
}}</MsButton> }}</MsButton>
<MsButton v-else @click="enableHandler(record)">{{ t('system.plugin.tableEnable') }}</MsButton>
<MsTableMoreAction <MsTableMoreAction
v-permission="['SYSTEM_PLUGIN:READ+DELETE']" v-permission="['SYSTEM_PLUGIN:READ+DELETE']"
:list="tableActions" :list="tableActions"

View File

@ -456,10 +456,12 @@
{ {
label: 'system.user.resetPassword', label: 'system.user.resetPassword',
eventTag: 'resetPassword', eventTag: 'resetPassword',
permission: ['SYSTEM_USER:READ+UPDATE'],
}, },
{ {
label: 'system.user.disable', label: 'system.user.disable',
eventTag: 'disabled', eventTag: 'disabled',
permission: ['SYSTEM_USER:READ+UPDATE'],
}, },
{ {
isDivider: true, isDivider: true,
@ -468,6 +470,7 @@
label: 'system.user.delete', label: 'system.user.delete',
eventTag: 'delete', eventTag: 'delete',
danger: true, danger: true,
permission: ['SYSTEM_USER:READ+DELETE'],
}, },
]; ];