fix: 系统设置bug修复&用例管理bug修复&任务中心调整
This commit is contained in:
parent
47399e6ba5
commit
95c1ade326
Binary file not shown.
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 490 KiB |
|
@ -217,7 +217,7 @@ export function addDemandRequest(data: CreateOrUpdateDemand) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新需求
|
// 更新需求
|
||||||
export function updateDemand(data: CreateOrUpdateDemand) {
|
export function updateDemandReq(data: CreateOrUpdateDemand) {
|
||||||
return MSR.post({ url: UpdateDemandUrl, data });
|
return MSR.post({ url: UpdateDemandUrl, data });
|
||||||
}
|
}
|
||||||
// 批量关联需求
|
// 批量关联需求
|
||||||
|
@ -239,7 +239,8 @@ export function getThirdDemandList(data: TableQueryParams) {
|
||||||
|
|
||||||
// 上传文件并关联用例
|
// 上传文件并关联用例
|
||||||
export function uploadOrAssociationFile(data: Record<string, any>) {
|
export function uploadOrAssociationFile(data: Record<string, any>) {
|
||||||
return MSR.uploadFile({ url: UploadOrAssociationFileUrl }, { request: data.request, fileList: [data.file] });
|
debugger;
|
||||||
|
return MSR.uploadFile({ url: UploadOrAssociationFileUrl }, { request: data.request, fileList: data.file });
|
||||||
}
|
}
|
||||||
// 转存文件
|
// 转存文件
|
||||||
export function transferFileRequest(data: OperationFile) {
|
export function transferFileRequest(data: OperationFile) {
|
||||||
|
|
|
@ -96,7 +96,7 @@ export function enableOrOffTemplate(organizationId: string, scene: SeneType) {
|
||||||
*/
|
*/
|
||||||
// 获取自定义字段列表(组织)
|
// 获取自定义字段列表(组织)
|
||||||
export function getFieldList(params: TableQueryParams) {
|
export function getFieldList(params: TableQueryParams) {
|
||||||
return MSR.get({ url: `${GetDefinedFieldListUrl}${params.scopedId}/${params.scene}` });
|
return MSR.get({ url: `${GetDefinedFieldListUrl}/${params.scopedId}/${params.scene}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建自定义字段(组织)
|
// 创建自定义字段(组织)
|
||||||
|
@ -154,7 +154,7 @@ export function updateOrdWorkStateFlow(data: UpdateWorkFlowSetting) {
|
||||||
*/
|
*/
|
||||||
// 获取自定义字段列表(组织)
|
// 获取自定义字段列表(组织)
|
||||||
export function getProjectFieldList(params: TableQueryParams) {
|
export function getProjectFieldList(params: TableQueryParams) {
|
||||||
return MSR.get({ url: `${GetDefinedProjectFieldListUrl}${params.scopedId}/${params.scene}` });
|
return MSR.get({ url: `${GetDefinedProjectFieldListUrl}/${params.scopedId}/${params.scene}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建自定义字段(组织)
|
// 创建自定义字段(组织)
|
||||||
|
|
|
@ -37,7 +37,7 @@ export const getOrdTemplateStateUrl = '/organization/template/enable/config';
|
||||||
// 系统设置-组织-自定义字段
|
// 系统设置-组织-自定义字段
|
||||||
|
|
||||||
// 获取自定义字段列表
|
// 获取自定义字段列表
|
||||||
export const GetDefinedFieldListUrl = '/organization/custom/field/list/';
|
export const GetDefinedFieldListUrl = '/organization/custom/field/list';
|
||||||
// 创建自定义字段
|
// 创建自定义字段
|
||||||
export const CreateFieldUrl = '/organization/custom/field/add';
|
export const CreateFieldUrl = '/organization/custom/field/add';
|
||||||
// 更新自定义字段
|
// 更新自定义字段
|
||||||
|
@ -67,7 +67,7 @@ export const OrdUpdateStateFlowUrl = '/organization/status/flow/setting/status/f
|
||||||
// 项目管理-模板-自定义字段
|
// 项目管理-模板-自定义字段
|
||||||
|
|
||||||
// 获取自定义字段列表
|
// 获取自定义字段列表
|
||||||
export const GetDefinedProjectFieldListUrl = '/project/custom/field/list/';
|
export const GetDefinedProjectFieldListUrl = '/project/custom/field/list';
|
||||||
// 创建自定义字段
|
// 创建自定义字段
|
||||||
export const CreateProjectFieldUrl = '/project/custom/field/add';
|
export const CreateProjectFieldUrl = '/project/custom/field/add';
|
||||||
// 更新自定义字段
|
// 更新自定义字段
|
||||||
|
|
|
@ -175,7 +175,12 @@
|
||||||
</a-checkbox-group>
|
</a-checkbox-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="delete-btn" :class="{ 'delete-btn:disabled': idx === 0 }" @click="handleDeleteItem(idx)">
|
<div
|
||||||
|
v-if="formModel.list.length > 1"
|
||||||
|
class="delete-btn"
|
||||||
|
:class="{ 'delete-btn:disabled': idx === 0 }"
|
||||||
|
@click="handleDeleteItem(idx)"
|
||||||
|
>
|
||||||
<icon-minus-circle />
|
<icon-minus-circle />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -305,7 +310,10 @@
|
||||||
* @description 删除条件
|
* @description 删除条件
|
||||||
*/
|
*/
|
||||||
const handleDeleteItem = (index: number) => {
|
const handleDeleteItem = (index: number) => {
|
||||||
if (index === 0) {
|
// if (index === 0) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
if (formModel.list.length === 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
formModel.list.splice(index, 1);
|
formModel.list.splice(index, 1);
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<template #title> {{ t('settings.navbar.task') }}</template>
|
<template #title> {{ t('settings.navbar.task') }}</template>
|
||||||
|
|
||||||
<div class="divider h-full">
|
<div class="divider h-full">
|
||||||
<TaskCenter group="system" mode="modal"></TaskCenter>
|
<TaskCenter group="project" mode="modal"></TaskCenter>
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -375,13 +375,13 @@ export const pathMap: PathMapItem[] = [
|
||||||
permission: [],
|
permission: [],
|
||||||
level: MENU_LEVEL[2],
|
level: MENU_LEVEL[2],
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// key: 'PROJECT_MANAGEMENT_PERMISSION_VERSION', // 项目管理-项目与权限-项目版本
|
key: 'PROJECT_MANAGEMENT_PERMISSION_VERSION', // 项目管理-项目与权限-项目版本
|
||||||
// locale: 'project.permission.projectVersion',
|
locale: 'project.permission.projectVersion',
|
||||||
// route: RouteEnum.PROJECT_MANAGEMENT_PERMISSION_VERSION,
|
route: RouteEnum.PROJECT_MANAGEMENT_PERMISSION_VERSION,
|
||||||
// permission: [],
|
permission: [],
|
||||||
// level: MENU_LEVEL[2],
|
level: MENU_LEVEL[2],
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
key: 'PROJECT_MANAGEMENT_PERMISSION_MEMBER', // 项目管理-项目与权限-成员
|
key: 'PROJECT_MANAGEMENT_PERMISSION_MEMBER', // 项目管理-项目与权限-成员
|
||||||
locale: 'project.permission.member',
|
locale: 'project.permission.member',
|
||||||
|
@ -412,6 +412,13 @@ export const pathMap: PathMapItem[] = [
|
||||||
permission: [],
|
permission: [],
|
||||||
level: MENU_LEVEL[2],
|
level: MENU_LEVEL[2],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'PROJECT_CUSTOM_FIELD', // 项目管理-模板管理-字段设置-新增字段
|
||||||
|
locale: 'system.orgTemplate.addField',
|
||||||
|
route: '',
|
||||||
|
permission: [],
|
||||||
|
level: MENU_LEVEL[2],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT', // 项目管理-模板管理列表
|
key: 'PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT', // 项目管理-模板管理列表
|
||||||
locale: 'menu.settings.organization.templateManagementList',
|
locale: 'menu.settings.organization.templateManagementList',
|
||||||
|
|
|
@ -75,6 +75,7 @@ export enum SettingRouteEnum {
|
||||||
SETTING_SYSTEM_RESOURCE_POOL_DETAIL = 'settingSystemResourcePoolDetail',
|
SETTING_SYSTEM_RESOURCE_POOL_DETAIL = 'settingSystemResourcePoolDetail',
|
||||||
SETTING_SYSTEM_AUTHORIZED_MANAGEMENT = 'settingSystemAuthorizedManagement',
|
SETTING_SYSTEM_AUTHORIZED_MANAGEMENT = 'settingSystemAuthorizedManagement',
|
||||||
SETTING_SYSTEM_LOG = 'settingSystemLog',
|
SETTING_SYSTEM_LOG = 'settingSystemLog',
|
||||||
|
SETTING_SYSTEM_TASK_CENTER = 'settingSystemTaskCenter',
|
||||||
SETTING_SYSTEM_PLUGIN_MANAGEMENT = 'settingSystemPluginManagement',
|
SETTING_SYSTEM_PLUGIN_MANAGEMENT = 'settingSystemPluginManagement',
|
||||||
SETTING_ORGANIZATION = 'settingOrganization',
|
SETTING_ORGANIZATION = 'settingOrganization',
|
||||||
SETTING_ORGANIZATION_MEMBER = 'settingOrganizationMember',
|
SETTING_ORGANIZATION_MEMBER = 'settingOrganizationMember',
|
||||||
|
|
|
@ -254,9 +254,9 @@ export interface DemandFormList {
|
||||||
// 创建需求&编辑需求
|
// 创建需求&编辑需求
|
||||||
export interface CreateOrUpdateDemand {
|
export interface CreateOrUpdateDemand {
|
||||||
id?: string;
|
id?: string;
|
||||||
caseId: string;
|
|
||||||
demandPlatform: string;
|
demandPlatform: string;
|
||||||
demandList?: DemandFormList[];
|
demandList?: DemandFormList[];
|
||||||
|
caseId?: string;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
// 转存文件
|
// 转存文件
|
||||||
|
|
|
@ -115,6 +115,7 @@ export interface ActionTemplateManage {
|
||||||
customFields?: CustomField[];
|
customFields?: CustomField[];
|
||||||
fieldType?: string;
|
fieldType?: string;
|
||||||
systemFields?: Record<string, any>[];
|
systemFields?: Record<string, any>[];
|
||||||
|
internal?: boolean; // 是否为系统模板
|
||||||
}
|
}
|
||||||
|
|
||||||
// 工作流列表字段
|
// 工作流列表字段
|
||||||
|
|
|
@ -197,6 +197,7 @@ const ProjectManagement: AppRouteRecordRaw = {
|
||||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_DETAIL,
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_DETAIL,
|
||||||
locale: 'menu.settings.organization.templateManagementDetail',
|
locale: 'menu.settings.organization.templateManagementDetail',
|
||||||
editLocale: 'menu.settings.organization.templateManagementEdit',
|
editLocale: 'menu.settings.organization.templateManagementEdit',
|
||||||
|
editTag: 'id',
|
||||||
query: ['type'],
|
query: ['type'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -289,17 +290,6 @@ const ProjectManagement: AppRouteRecordRaw = {
|
||||||
isTopMenu: true,
|
isTopMenu: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// 任务中心
|
|
||||||
{
|
|
||||||
path: 'taskCenter',
|
|
||||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TASK_CENTER,
|
|
||||||
component: () => import('@/views/project-management/taskCenter/index.vue'),
|
|
||||||
meta: {
|
|
||||||
locale: 'menu.projectManagement.taskCenter',
|
|
||||||
roles: ['*'],
|
|
||||||
isTopMenu: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// 菜单管理-误报规则
|
// 菜单管理-误报规则
|
||||||
{
|
{
|
||||||
path: 'errorReportRule',
|
path: 'errorReportRule',
|
||||||
|
|
|
@ -150,6 +150,17 @@ const Setting: AppRouteRecordRaw = {
|
||||||
isTopMenu: true,
|
isTopMenu: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// 任务中心
|
||||||
|
{
|
||||||
|
path: 'taskCenter',
|
||||||
|
name: SettingRouteEnum.SETTING_SYSTEM_TASK_CENTER,
|
||||||
|
component: () => import('@/views/setting/system/taskCenter/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: 'menu.projectManagement.taskCenter',
|
||||||
|
roles: ['*'],
|
||||||
|
isTopMenu: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'pluginManager',
|
path: 'pluginManager',
|
||||||
name: SettingRouteEnum.SETTING_SYSTEM_PLUGIN_MANAGEMENT,
|
name: SettingRouteEnum.SETTING_SYSTEM_PLUGIN_MANAGEMENT,
|
||||||
|
|
|
@ -1,58 +1,36 @@
|
||||||
<template>
|
<template>
|
||||||
<MsBaseTable v-bind="propsRes" ref="tableRef" v-on="propsEvent">
|
<MsBaseTable v-bind="propsRes" ref="tableRef" :hoverable="false" v-on="propsEvent" @change="changeHandler">
|
||||||
<template #index="{ rowIndex }">
|
<template #index="{ rowIndex }">
|
||||||
<div class="circle text-xs font-medium"> {{ rowIndex + 1 }}</div>
|
<div class="circle text-xs font-medium"> {{ rowIndex + 1 }}</div>
|
||||||
</template>
|
</template>
|
||||||
<template #caseStep="{ record }">
|
<template #caseStep="{ record }">
|
||||||
|
<!-- v-if="record.showStep" -->
|
||||||
<a-textarea
|
<a-textarea
|
||||||
v-if="record.showStep"
|
|
||||||
:ref="(el: refItem) => setStepRefMap(el, record)"
|
:ref="(el: refItem) => setStepRefMap(el, record)"
|
||||||
v-model="record.step"
|
v-model="record.step"
|
||||||
size="mini"
|
size="mini"
|
||||||
:auto-size="true"
|
:auto-size="true"
|
||||||
class="w-max-[267px]"
|
class="w-max-[267px] param-input"
|
||||||
:placeholder="t('system.orgTemplate.stepTip')"
|
:placeholder="t('system.orgTemplate.stepTip')"
|
||||||
@blur="blurHandler(record, 'step')"
|
@blur="blurHandler(record, 'step')"
|
||||||
/>
|
/>
|
||||||
<div v-else-if="record.step && !record.showStep" class="w-full cursor-pointer" @click="edit(record, 'step')">{{
|
|
||||||
record.step
|
|
||||||
}}</div>
|
|
||||||
<div
|
|
||||||
v-else-if="!record.caseStep && !record.showStep"
|
|
||||||
class="placeholder w-full cursor-pointer text-[var(--color-text-brand)]"
|
|
||||||
@click="edit(record, 'step')"
|
|
||||||
>{{ t('system.orgTemplate.stepTip') }}</div
|
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
<template #expectedResult="{ record }">
|
<template #expectedResult="{ record }">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
v-if="record.showExpected"
|
|
||||||
:ref="(el: refItem) => setExpectedRefMap(el, record)"
|
:ref="(el: refItem) => setExpectedRefMap(el, record)"
|
||||||
v-model="record.expected"
|
v-model="record.expected"
|
||||||
:max-length="1000"
|
:max-length="1000"
|
||||||
size="mini"
|
size="mini"
|
||||||
:auto-size="true"
|
:auto-size="true"
|
||||||
class="w-max-[267px]"
|
class="w-max-[267px] param-input"
|
||||||
:placeholder="t('system.orgTemplate.expectationTip')"
|
:placeholder="t('system.orgTemplate.expectationTip')"
|
||||||
@blur="blurHandler(record, 'expected')"
|
@blur="blurHandler(record, 'expected')"
|
||||||
/>
|
/>
|
||||||
<div
|
|
||||||
v-else-if="record.expected && !record.showExpected"
|
|
||||||
class="w-full cursor-pointer"
|
|
||||||
@click="edit(record, 'expected')"
|
|
||||||
>{{ record.expected }}</div
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-else-if="!record.expected && !record.showExpected"
|
|
||||||
class="placeholder w-full cursor-pointer text-[var(--color-text-brand)]"
|
|
||||||
@click="edit(record, 'expected')"
|
|
||||||
>{{ t('system.orgTemplate.expectationTip') }}</div
|
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
<template #operation="{ record }">
|
<template #operation="{ record }">
|
||||||
<MsTableMoreAction
|
<MsTableMoreAction
|
||||||
v-if="!record.internal"
|
v-if="!record.internal"
|
||||||
:list="moreActions"
|
:list="moreActionList"
|
||||||
@select="(item:ActionsItem) => handleMoreActionSelect(item,record)"
|
@select="(item:ActionsItem) => handleMoreActionSelect(item,record)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -67,6 +45,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { TableChangeExtra, TableData } from '@arco-design/web-vue';
|
||||||
|
|
||||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
|
@ -95,6 +74,17 @@
|
||||||
|
|
||||||
const emit = defineEmits(['update:stepList']);
|
const emit = defineEmits(['update:stepList']);
|
||||||
|
|
||||||
|
// 步骤描述
|
||||||
|
const stepData = ref<StepList[]>([
|
||||||
|
{
|
||||||
|
id: getGenerateId(),
|
||||||
|
step: '',
|
||||||
|
expected: '',
|
||||||
|
showStep: false,
|
||||||
|
showExpected: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
const templateFieldColumns = ref<MsTableColumn>([
|
const templateFieldColumns = ref<MsTableColumn>([
|
||||||
{
|
{
|
||||||
title: 'system.orgTemplate.numberIndex',
|
title: 'system.orgTemplate.numberIndex',
|
||||||
|
@ -151,6 +141,10 @@
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const moreActionList = computed(() => {
|
||||||
|
return stepData.value.length <= 1 ? moreActions.slice(0, moreActions.length - 2) : moreActions;
|
||||||
|
});
|
||||||
|
|
||||||
const { propsRes, propsEvent, setProps } = useTable(undefined, {
|
const { propsRes, propsEvent, setProps } = useTable(undefined, {
|
||||||
tableKey: TableKeyEnum.CASE_MANAGEMENT_DETAIL_TABLE,
|
tableKey: TableKeyEnum.CASE_MANAGEMENT_DETAIL_TABLE,
|
||||||
columns: templateFieldColumns.value,
|
columns: templateFieldColumns.value,
|
||||||
|
@ -163,17 +157,6 @@
|
||||||
enableDrag: true,
|
enableDrag: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 步骤描述
|
|
||||||
const stepData = ref<StepList[]>([
|
|
||||||
{
|
|
||||||
id: getGenerateId(),
|
|
||||||
step: '',
|
|
||||||
expected: '',
|
|
||||||
showStep: false,
|
|
||||||
showExpected: false,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 复制步骤
|
// 复制步骤
|
||||||
function copyStep(record: StepList) {
|
function copyStep(record: StepList) {
|
||||||
stepData.value.push({
|
stepData.value.push({
|
||||||
|
@ -292,6 +275,13 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function changeHandler(data: TableData[], extra: TableChangeExtra, currentData: TableData[]) {
|
||||||
|
if (!currentData || currentData.length === 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stepData.value = data as StepList[];
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => stepData.value,
|
() => stepData.value,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
@ -326,4 +316,18 @@
|
||||||
color: var(--color-text-4);
|
color: var(--color-text-4);
|
||||||
background: var(--color-text-n8);
|
background: var(--color-text-n8);
|
||||||
}
|
}
|
||||||
|
:deep(.param-input:not(.arco-input-focus, .arco-select-view-focus)) {
|
||||||
|
&:not(:hover) {
|
||||||
|
border-color: transparent !important;
|
||||||
|
.arco-input::placeholder {
|
||||||
|
@apply invisible;
|
||||||
|
}
|
||||||
|
.arco-select-view-icon {
|
||||||
|
@apply invisible;
|
||||||
|
}
|
||||||
|
.arco-select-view-value {
|
||||||
|
color: var(--color-text-brand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -91,7 +91,13 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div ref="wrapperRef" class="wrapperRef h-full bg-white">
|
<div
|
||||||
|
ref="wrapperRef"
|
||||||
|
class="wrapperRef bg-white"
|
||||||
|
:style="{
|
||||||
|
height: isFullScreen ? '100%' : 'calc(100% - 86px)',
|
||||||
|
}"
|
||||||
|
>
|
||||||
<MsSplitBox
|
<MsSplitBox
|
||||||
ref="wrapperRef"
|
ref="wrapperRef"
|
||||||
:class="isFullScreen ? 'h-[100%]' : 'h-[calc(100% - 78px)]'"
|
:class="isFullScreen ? 'h-[100%]' : 'h-[calc(100% - 78px)]'"
|
||||||
|
@ -365,7 +371,7 @@
|
||||||
|
|
||||||
const editLoading = ref<boolean>(false);
|
const editLoading = ref<boolean>(false);
|
||||||
|
|
||||||
function updateSuccess() {
|
async function updateSuccess() {
|
||||||
detailDrawerRef.value?.initDetail();
|
detailDrawerRef.value?.initDetail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +397,7 @@
|
||||||
followLoading.value = true;
|
followLoading.value = true;
|
||||||
try {
|
try {
|
||||||
if (detailInfo.value.id) {
|
if (detailInfo.value.id) {
|
||||||
await followerCaseRequest({ userId: userId.value as string, functionalCaseId: detailInfo.value.id });
|
await followerCaseRequest({ userId: userStore.userInfo.id as string, functionalCaseId: detailInfo.value.id });
|
||||||
updateSuccess();
|
updateSuccess();
|
||||||
Message.success(
|
Message.success(
|
||||||
detailInfo.value.followFlag
|
detailInfo.value.followFlag
|
||||||
|
@ -440,8 +446,6 @@
|
||||||
const formRules = ref<FormItem[]>([]);
|
const formRules = ref<FormItem[]>([]);
|
||||||
const formItem = ref<FormRuleItem[]>([]);
|
const formItem = ref<FormRuleItem[]>([]);
|
||||||
|
|
||||||
const isDisabled = ref<boolean>(false);
|
|
||||||
|
|
||||||
// 表单配置项
|
// 表单配置项
|
||||||
const options = {
|
const options = {
|
||||||
resetBtn: false, // 不展示默认配置的重置和提交
|
resetBtn: false, // 不展示默认配置的重置和提交
|
||||||
|
@ -473,7 +477,15 @@
|
||||||
function initForm() {
|
function initForm() {
|
||||||
formRules.value = customFields.value.map((item: any) => {
|
formRules.value = customFields.value.map((item: any) => {
|
||||||
const multipleType = ['MULTIPLE_SELECT', 'CHECKBOX', 'MULTIPLE_MEMBER', 'MULTIPLE_INPUT'];
|
const multipleType = ['MULTIPLE_SELECT', 'CHECKBOX', 'MULTIPLE_MEMBER', 'MULTIPLE_INPUT'];
|
||||||
const currentDefaultValue = multipleType.includes(item.type) ? JSON.parse(item.defaultValue) : item.defaultValue;
|
const numberType = ['INT', 'FLOAT'];
|
||||||
|
let currentDefaultValue;
|
||||||
|
if (numberType.includes(item.type)) {
|
||||||
|
currentDefaultValue = item.defaultValue * 1;
|
||||||
|
} else if (multipleType.includes(item.type)) {
|
||||||
|
currentDefaultValue = JSON.parse(item.defaultValue);
|
||||||
|
} else {
|
||||||
|
currentDefaultValue = item.defaultValue;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
type: item.type,
|
type: item.type,
|
||||||
|
|
|
@ -197,7 +197,20 @@
|
||||||
:pagination="propsRes.msPagination!"
|
:pagination="propsRes.msPagination!"
|
||||||
@success="initData()"
|
@success="initData()"
|
||||||
/>
|
/>
|
||||||
<AddDemandModal v-model:visible="showDemandModel" :case-id="caseId" :form="modelForm" />
|
<AddDemandModal
|
||||||
|
ref="demandRef"
|
||||||
|
v-model:visible="showDemandModel"
|
||||||
|
:loading="confirmLoading"
|
||||||
|
:case-id="caseId"
|
||||||
|
:form="modelForm"
|
||||||
|
@save="actionDemand"
|
||||||
|
/>
|
||||||
|
<ThirdDemandDrawer
|
||||||
|
v-model:visible="showThirdDrawer"
|
||||||
|
:case-id="caseId"
|
||||||
|
:drawer-loading="drawerLoading"
|
||||||
|
@save="saveThirdDemand"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -223,9 +236,11 @@
|
||||||
import FeatureCaseTree from './caseTree.vue';
|
import FeatureCaseTree from './caseTree.vue';
|
||||||
import ExportExcelDrawer from './exportExcelDrawer.vue';
|
import ExportExcelDrawer from './exportExcelDrawer.vue';
|
||||||
import AddDemandModal from './tabContent/tabDemand/addDemandModal.vue';
|
import AddDemandModal from './tabContent/tabDemand/addDemandModal.vue';
|
||||||
|
import ThirdDemandDrawer from './tabContent/tabDemand/thirdDemandDrawer.vue';
|
||||||
import TableFormChange from './tableFormChange.vue';
|
import TableFormChange from './tableFormChange.vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
batchAssociationDemand,
|
||||||
batchCopyToModules,
|
batchCopyToModules,
|
||||||
batchDeleteCase,
|
batchDeleteCase,
|
||||||
batchMoveToModules,
|
batchMoveToModules,
|
||||||
|
@ -247,6 +262,7 @@
|
||||||
import type {
|
import type {
|
||||||
CaseManagementTable,
|
CaseManagementTable,
|
||||||
CaseModuleQueryParams,
|
CaseModuleQueryParams,
|
||||||
|
CreateOrUpdateDemand,
|
||||||
CustomAttributes,
|
CustomAttributes,
|
||||||
DemandItem,
|
DemandItem,
|
||||||
DragCase,
|
DragCase,
|
||||||
|
@ -472,6 +488,7 @@
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
sortable: {
|
sortable: {
|
||||||
sortDirections: ['ascend', 'descend'],
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
sorter: true,
|
||||||
},
|
},
|
||||||
width: 200,
|
width: 200,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
|
@ -682,6 +699,7 @@
|
||||||
tableKey: TableKeyEnum.CASE_MANAGEMENT_TABLE,
|
tableKey: TableKeyEnum.CASE_MANAGEMENT_TABLE,
|
||||||
scroll: { x: scrollWidth.value },
|
scroll: { x: scrollWidth.value },
|
||||||
selectable: true,
|
selectable: true,
|
||||||
|
showJumpMethod: true,
|
||||||
showSetting: true,
|
showSetting: true,
|
||||||
heightUsed: 374,
|
heightUsed: 374,
|
||||||
enableDrag: true,
|
enableDrag: true,
|
||||||
|
@ -942,8 +960,13 @@
|
||||||
function addDemand() {
|
function addDemand() {
|
||||||
showDemandModel.value = true;
|
showDemandModel.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const showThirdDrawer = ref<boolean>(false);
|
||||||
|
|
||||||
// 关联需求
|
// 关联需求
|
||||||
function handleAssociatedDemand() {}
|
function handleAssociatedDemand() {
|
||||||
|
showThirdDrawer.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
||||||
batchParams.value = params;
|
batchParams.value = params;
|
||||||
|
@ -1147,9 +1170,10 @@
|
||||||
|
|
||||||
// 拖拽排序
|
// 拖拽排序
|
||||||
async function changeHandler(data: TableData[], extra: TableChangeExtra, currentData: TableData[]) {
|
async function changeHandler(data: TableData[], extra: TableChangeExtra, currentData: TableData[]) {
|
||||||
if (currentData.length === 1) {
|
if (!currentData || currentData.length === 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extra && extra.dragTarget?.id) {
|
if (extra && extra.dragTarget?.id) {
|
||||||
const params: DragCase = {
|
const params: DragCase = {
|
||||||
projectId: currentProjectId.value,
|
projectId: currentProjectId.value,
|
||||||
|
@ -1178,15 +1202,78 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showCaseDetailEvent(record: TableData, column: TableColumnData, ev: Event) {
|
// function showCaseDetailEvent(record: TableData, column: TableColumnData, ev: Event) {
|
||||||
showDetailDrawer.value = false;
|
// showDetailDrawer.value = false;
|
||||||
if (column.title === 'name' || column.title === 'num') {
|
// if (column.title === 'name' || column.title === 'num') {
|
||||||
const rowIndex = propsRes.value.data.map((item: any) => item.id).indexOf(record.id);
|
// const rowIndex = propsRes.value.data.map((item: any) => item.id).indexOf(record.id);
|
||||||
showDetailDrawer.value = true;
|
// showDetailDrawer.value = true;
|
||||||
activeDetailId.value = record.id;
|
// activeDetailId.value = record.id;
|
||||||
activeCaseIndex.value = rowIndex;
|
// activeCaseIndex.value = rowIndex;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 批量添加需求
|
||||||
|
const confirmLoading = ref<boolean>(false);
|
||||||
|
const demandRef = ref();
|
||||||
|
async function actionDemand(param: CreateOrUpdateDemand, isContinue: boolean) {
|
||||||
|
try {
|
||||||
|
confirmLoading.value = true;
|
||||||
|
const { demandPlatform, demandList } = param;
|
||||||
|
const batchAddParams: CreateOrUpdateDemand = {
|
||||||
|
selectIds: batchParams.value?.selectAll ? [] : batchParams.value.selectedIds,
|
||||||
|
selectAll: !!batchParams.value?.selectAll,
|
||||||
|
excludeIds: batchParams.value?.excludeIds || [],
|
||||||
|
condition: { keyword: keyword.value },
|
||||||
|
projectId: currentProjectId.value,
|
||||||
|
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
|
||||||
|
moduleId: selectedModuleKeys.value[0],
|
||||||
|
demandPlatform,
|
||||||
|
demandList,
|
||||||
|
};
|
||||||
|
await batchAssociationDemand(batchAddParams);
|
||||||
|
if (!isContinue) {
|
||||||
|
showDemandModel.value = false;
|
||||||
|
}
|
||||||
|
demandRef.value.resetForm();
|
||||||
|
Message.success(t('common.addSuccess'));
|
||||||
|
resetSelector();
|
||||||
|
initData();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
confirmLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 批量关联需求
|
||||||
|
const drawerLoading = ref<boolean>(false);
|
||||||
|
async function saveThirdDemand(params: CreateOrUpdateDemand) {
|
||||||
|
try {
|
||||||
|
drawerLoading.value = true;
|
||||||
|
const { demandPlatform, demandList } = params;
|
||||||
|
const batchAddParams: CreateOrUpdateDemand = {
|
||||||
|
selectIds: batchParams.value?.selectAll ? [] : batchParams.value.selectedIds,
|
||||||
|
selectAll: !!batchParams.value?.selectAll,
|
||||||
|
excludeIds: batchParams.value?.excludeIds || [],
|
||||||
|
condition: { keyword: keyword.value },
|
||||||
|
projectId: currentProjectId.value,
|
||||||
|
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
|
||||||
|
moduleId: selectedModuleKeys.value[0],
|
||||||
|
demandPlatform,
|
||||||
|
demandList,
|
||||||
|
};
|
||||||
|
await batchAssociationDemand(batchAddParams);
|
||||||
|
Message.success(t('caseManagement.featureCase.associatedSuccess'));
|
||||||
|
showThirdDrawer.value = false;
|
||||||
|
resetSelector();
|
||||||
|
initData();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
drawerLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (route.query.id) {
|
if (route.query.id) {
|
||||||
showCaseDetail(route.query.id as string, 0);
|
showCaseDetail(route.query.id as string, 0);
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a-button type="secondary" @click="handleCancel">{{ t('common.cancel') }}</a-button>
|
<a-button type="secondary" @click="handleCancel">{{ t('common.cancel') }}</a-button>
|
||||||
<a-button v-if="!form.id" type="secondary" @click="handleOK(true)">{{ t('ms.dialog.saveContinue') }}</a-button>
|
<a-button v-if="!form.id" type="secondary" @click="handleOK(true)">{{ t('ms.dialog.saveContinue') }}</a-button>
|
||||||
<a-button class="ml-[12px]" type="primary" :loading="confirmLoading" @click="handleOK(false)">
|
<a-button class="ml-[12px]" type="primary" :loading="props.loading" @click="handleOK(false)">
|
||||||
{{ updateName ? t('common.update') : t('common.create') }}
|
{{ updateName ? t('common.update') : t('common.create') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -54,7 +54,6 @@
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { FormInstance, Message, ValidatedError } from '@arco-design/web-vue';
|
import { FormInstance, Message, ValidatedError } from '@arco-design/web-vue';
|
||||||
|
|
||||||
import { addDemandRequest, updateDemand } from '@/api/modules/case-management/featureCase';
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { useAppStore } from '@/store';
|
import { useAppStore } from '@/store';
|
||||||
|
|
||||||
|
@ -67,11 +66,13 @@
|
||||||
caseId: string;
|
caseId: string;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
form: DemandItem;
|
form: DemandItem;
|
||||||
|
loading: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:visible', v: boolean): void;
|
(e: 'update:visible', v: boolean): void;
|
||||||
(e: 'success'): void;
|
(e: 'success'): void;
|
||||||
|
(e: 'save', params: CreateOrUpdateDemand, isContinue: boolean): void;
|
||||||
}>();
|
}>();
|
||||||
const pageConfig = computed(() => appStore.pageConfig);
|
const pageConfig = computed(() => appStore.pageConfig);
|
||||||
const form = ref<CreateOrUpdateDemand>({
|
const form = ref<CreateOrUpdateDemand>({
|
||||||
|
@ -84,7 +85,7 @@
|
||||||
|
|
||||||
const showModal = ref<boolean>(false);
|
const showModal = ref<boolean>(false);
|
||||||
|
|
||||||
const confirmLoading = ref<boolean>(false);
|
// const confirmLoading = ref<boolean>(false);
|
||||||
|
|
||||||
const initModelForm: DemandFormList = {
|
const initModelForm: DemandFormList = {
|
||||||
demandId: '',
|
demandId: '',
|
||||||
|
@ -112,30 +113,12 @@
|
||||||
function handleOK(isContinue: boolean) {
|
function handleOK(isContinue: boolean) {
|
||||||
demandFormRef.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => {
|
demandFormRef.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => {
|
||||||
if (!errors) {
|
if (!errors) {
|
||||||
try {
|
const { demandId, demandName, demandUrl } = modelForm.value;
|
||||||
const { demandId, demandName, demandUrl } = modelForm.value;
|
const params: CreateOrUpdateDemand = {
|
||||||
confirmLoading.value = true;
|
...form.value,
|
||||||
const params: CreateOrUpdateDemand = {
|
demandList: [{ demandId, demandName, demandUrl }],
|
||||||
...form.value,
|
};
|
||||||
demandList: [{ demandId, demandName, demandUrl }],
|
emit('save', params, isContinue);
|
||||||
};
|
|
||||||
if (form.value.id) {
|
|
||||||
await updateDemand(params);
|
|
||||||
Message.success(t('common.updateSuccess'));
|
|
||||||
} else {
|
|
||||||
await addDemandRequest(params);
|
|
||||||
Message.success(t('common.addSuccess'));
|
|
||||||
}
|
|
||||||
if (!isContinue) {
|
|
||||||
handleCancel();
|
|
||||||
}
|
|
||||||
resetForm();
|
|
||||||
emit('success');
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
} finally {
|
|
||||||
confirmLoading.value = false;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -171,6 +154,10 @@
|
||||||
updateName.value = val.demandName;
|
updateName.value = val.demandName;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
resetForm,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
@ -25,7 +25,15 @@
|
||||||
@update="updateDemand"
|
@update="updateDemand"
|
||||||
@create="addDemand"
|
@create="addDemand"
|
||||||
></AssociatedDemandTable>
|
></AssociatedDemandTable>
|
||||||
<AddDemandModal v-model:visible="showAddModel" :case-id="props.caseId" :form="modelForm" @success="searchList()" />
|
<AddDemandModal
|
||||||
|
ref="demandModalRef"
|
||||||
|
v-model:visible="showAddModel"
|
||||||
|
:case-id="props.caseId"
|
||||||
|
:form="modelForm"
|
||||||
|
:loading="confirmLoading"
|
||||||
|
@save="saveHandler"
|
||||||
|
@success="searchList()"
|
||||||
|
/>
|
||||||
<MsDrawer
|
<MsDrawer
|
||||||
v-model:visible="linkDemandDrawer"
|
v-model:visible="linkDemandDrawer"
|
||||||
:ok-disabled="tableSelected.length < 1"
|
:ok-disabled="tableSelected.length < 1"
|
||||||
|
@ -81,12 +89,12 @@
|
||||||
import AddDemandModal from './addDemandModal.vue';
|
import AddDemandModal from './addDemandModal.vue';
|
||||||
import AssociatedDemandTable from './associatedDemandTable.vue';
|
import AssociatedDemandTable from './associatedDemandTable.vue';
|
||||||
|
|
||||||
import { addDemandRequest, getThirdDemandList } from '@/api/modules/case-management/featureCase';
|
import { addDemandRequest, getThirdDemandList, updateDemandReq } from '@/api/modules/case-management/featureCase';
|
||||||
import { getCaseRelatedInfo } from '@/api/modules/project-management/menuManagement';
|
import { getCaseRelatedInfo } from '@/api/modules/project-management/menuManagement';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { useAppStore } from '@/store';
|
import { useAppStore } from '@/store';
|
||||||
|
|
||||||
import type { DemandItem } from '@/models/caseManagement/featureCase';
|
import type { CreateOrUpdateDemand, DemandItem } from '@/models/caseManagement/featureCase';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -285,6 +293,31 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const confirmLoading = ref<boolean>(false);
|
||||||
|
const demandModalRef = ref();
|
||||||
|
|
||||||
|
async function saveHandler(param: CreateOrUpdateDemand, isContinue: boolean) {
|
||||||
|
try {
|
||||||
|
confirmLoading.value = true;
|
||||||
|
if (param.id) {
|
||||||
|
await updateDemandReq(param);
|
||||||
|
Message.success(t('common.updateSuccess'));
|
||||||
|
} else {
|
||||||
|
await addDemandRequest(param);
|
||||||
|
Message.success(t('common.addSuccess'));
|
||||||
|
}
|
||||||
|
if (!isContinue) {
|
||||||
|
showAddModel.value = false;
|
||||||
|
}
|
||||||
|
demandModalRef.value.resetForm();
|
||||||
|
demandRef.value.initData();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
confirmLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
try {
|
try {
|
||||||
const result = await getCaseRelatedInfo(currentProjectId.value);
|
const result = await getCaseRelatedInfo(currentProjectId.value);
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
<template>
|
||||||
|
<MsDrawer
|
||||||
|
v-model:visible="innerLinkDemandVisible"
|
||||||
|
:ok-disabled="tableSelected.length < 1"
|
||||||
|
:mask="false"
|
||||||
|
:title="t('caseManagement.featureCase.associatedDemand')"
|
||||||
|
:ok-text="t('caseManagement.featureCase.associated')"
|
||||||
|
:ok-loading="props.drawerLoading"
|
||||||
|
:width="960"
|
||||||
|
unmount-on-close
|
||||||
|
:show-continue="false"
|
||||||
|
@confirm="handleDrawerConfirm"
|
||||||
|
@cancel="handleDrawerCancel"
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<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"
|
||||||
|
:max-length="255"
|
||||||
|
:placeholder="t('project.member.searchMember')"
|
||||||
|
allow-clear
|
||||||
|
class="mx-[8px] w-[240px]"
|
||||||
|
@search="searchHandler"
|
||||||
|
@press-enter="searchHandler"
|
||||||
|
></a-input-search>
|
||||||
|
</div>
|
||||||
|
<ms-base-table ref="tableRef" v-bind="propsRes" v-on="propsEvent">
|
||||||
|
<template #demandName="{ record }">
|
||||||
|
<span class="ml-1 text-[rgb(var(--primary-5))]">
|
||||||
|
{{ record.demandName }}
|
||||||
|
<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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||||
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
|
import type { MsTableColumn, MsTableColumnData } from '@/components/pure/ms-table/type';
|
||||||
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
|
|
||||||
|
import { getThirdDemandList } from '@/api/modules/case-management/featureCase';
|
||||||
|
import { getCaseRelatedInfo } from '@/api/modules/project-management/menuManagement';
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { useAppStore } from '@/store';
|
||||||
|
|
||||||
|
import type { CreateOrUpdateDemand } from '@/models/caseManagement/featureCase';
|
||||||
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
const currentProjectId = computed(() => appStore.currentProjectId);
|
||||||
|
const props = defineProps<{
|
||||||
|
visible: boolean;
|
||||||
|
caseId: string;
|
||||||
|
drawerLoading: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:visible', visible: boolean): void;
|
||||||
|
(e: 'save', params: CreateOrUpdateDemand): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const innerLinkDemandVisible = useVModel(props, 'visible', emit);
|
||||||
|
|
||||||
|
const platformKeyword = ref<string>('');
|
||||||
|
const columns: MsTableColumn = [
|
||||||
|
{
|
||||||
|
title: 'caseManagement.featureCase.tableColumnID',
|
||||||
|
slotName: 'demandId',
|
||||||
|
dataIndex: 'demandId',
|
||||||
|
width: 200,
|
||||||
|
showTooltip: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'caseManagement.featureCase.tableColumnName',
|
||||||
|
slotName: 'demandName',
|
||||||
|
dataIndex: 'demandName',
|
||||||
|
width: 300,
|
||||||
|
showTooltip: 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 customFields = ref<Record<string, any>[]>([]);
|
||||||
|
|
||||||
|
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getThirdDemandList, {
|
||||||
|
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEMAND_PLATFORM,
|
||||||
|
columns: fullColumns.value,
|
||||||
|
rowKey: 'demandId',
|
||||||
|
scroll: { x: '100%' },
|
||||||
|
selectable: true,
|
||||||
|
showSetting: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tableSelected = computed(() => {
|
||||||
|
const selectIds = [...propsRes.value.selectedKeys];
|
||||||
|
return propsRes.value.data.filter((item: any) => selectIds.indexOf(item.demandId) > -1);
|
||||||
|
});
|
||||||
|
|
||||||
|
const platformInfo = ref<Record<string, any>>({});
|
||||||
|
function getPlatName() {
|
||||||
|
switch (platformInfo.value.platform_key) {
|
||||||
|
case 'zentao':
|
||||||
|
return t('caseManagement.featureCase.zentao');
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
emit('save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDrawerCancel() {
|
||||||
|
innerLinkDemandVisible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 initData = async () => {
|
||||||
|
setLoadListParams({ keyword: platformKeyword.value, projectId: currentProjectId.value });
|
||||||
|
loadList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchHandler = () => {
|
||||||
|
initData();
|
||||||
|
resetSelector();
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableRef = ref();
|
||||||
|
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];
|
||||||
|
} catch (error) {
|
||||||
|
tableRef.value.initColumn(columns);
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
try {
|
||||||
|
const result = await getCaseRelatedInfo(currentProjectId.value);
|
||||||
|
if (result && result.platform_key) {
|
||||||
|
platformInfo.value = { ...result };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => innerLinkDemandVisible.value,
|
||||||
|
async (val) => {
|
||||||
|
if (val) {
|
||||||
|
resetSelector();
|
||||||
|
await initColumn();
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -66,9 +66,11 @@
|
||||||
v-model:filed-ids="textDescriptionFileIds"
|
v-model:filed-ids="textDescriptionFileIds"
|
||||||
:upload-image="handleUploadImage"
|
:upload-image="handleUploadImage"
|
||||||
/>
|
/>
|
||||||
<div v-if="detailForm.caseEditType === 'TEXT' && !isEditPreposition">{{
|
<div
|
||||||
detailForm.textDescription || '-'
|
v-if="detailForm.caseEditType === 'TEXT' && !isEditPreposition"
|
||||||
}}</div>
|
v-dompurify-html="detailForm.textDescription || '-'"
|
||||||
|
class="text-[var(--color-text-3)]"
|
||||||
|
></div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-if="detailForm.caseEditType === 'TEXT'"
|
v-if="detailForm.caseEditType === 'TEXT'"
|
||||||
|
@ -81,7 +83,7 @@
|
||||||
v-model:filed-ids="expectedResultFileIds"
|
v-model:filed-ids="expectedResultFileIds"
|
||||||
:upload-image="handleUploadImage"
|
:upload-image="handleUploadImage"
|
||||||
/>
|
/>
|
||||||
<div v-else class="text-[var(--color-text-3)]" v-html="detailForm.description || '-'"></div>
|
<div v-else v-dompurify-html="detailForm.expectedResult || '-'" class="text-[var(--color-text-3)]"></div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item field="description" :label="t('caseManagement.featureCase.remark')">
|
<a-form-item field="description" :label="t('caseManagement.featureCase.remark')">
|
||||||
<MsRichText
|
<MsRichText
|
||||||
|
@ -601,10 +603,21 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
async function startUpload() {
|
async function startUpload(fileIds?: string[]) {
|
||||||
await sleep(300);
|
try {
|
||||||
await fileListRef.value?.startUpload();
|
const params = {
|
||||||
emit('updateSuccess');
|
request: {
|
||||||
|
caseId: detailForm.value.id,
|
||||||
|
projectId: currentProjectId.value,
|
||||||
|
fileIds,
|
||||||
|
},
|
||||||
|
file: fileList.value.filter((item) => item.status === 'init').map((item) => item.file),
|
||||||
|
};
|
||||||
|
await uploadOrAssociationFile(params);
|
||||||
|
emit('updateSuccess');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 文件列表单个上传
|
// 文件列表单个上传
|
||||||
watch(
|
watch(
|
||||||
|
@ -620,7 +633,9 @@
|
||||||
// 处理关联文件
|
// 处理关联文件
|
||||||
function saveSelectAssociatedFile(fileData: AssociatedList[]) {
|
function saveSelectAssociatedFile(fileData: AssociatedList[]) {
|
||||||
const fileResultList = fileData.map((fileInfo) => convertToFile(fileInfo));
|
const fileResultList = fileData.map((fileInfo) => convertToFile(fileInfo));
|
||||||
fileList.value.push(...fileResultList);
|
// fileList.value.push(...fileResultList);
|
||||||
|
const fileIds = fileResultList.map((item: any) => item.uid);
|
||||||
|
startUpload(fileIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新文件
|
// 更新文件
|
||||||
|
|
|
@ -252,5 +252,5 @@ export default {
|
||||||
'caseManagement.featureCase.defectSource': 'defect Source',
|
'caseManagement.featureCase.defectSource': 'defect Source',
|
||||||
'caseManagement.featureCase.sortSuccess': 'Sort successfully',
|
'caseManagement.featureCase.sortSuccess': 'Sort successfully',
|
||||||
'caseManagement.featureCase.zentao': 'zentao',
|
'caseManagement.featureCase.zentao': 'zentao',
|
||||||
'caseManagement.featureCase.searchPlaceholder': 'Search by id or name',
|
'caseManagement.featureCase.searchPlaceholder': 'Search by ID or name',
|
||||||
};
|
};
|
||||||
|
|
|
@ -247,5 +247,5 @@ export default {
|
||||||
'caseManagement.featureCase.defectSource': '缺陷来源',
|
'caseManagement.featureCase.defectSource': '缺陷来源',
|
||||||
'caseManagement.featureCase.sortSuccess': '排序成功',
|
'caseManagement.featureCase.sortSuccess': '排序成功',
|
||||||
'caseManagement.featureCase.zentao': '禅道',
|
'caseManagement.featureCase.zentao': '禅道',
|
||||||
'caseManagement.featureCase.searchPlaceholder': '通过id或名称搜索',
|
'caseManagement.featureCase.searchPlaceholder': '通过ID或名称搜索',
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,9 +26,13 @@
|
||||||
:rules="[{ required: true, message: t('login.form.userName.errMsg') }]"
|
:rules="[{ required: true, message: t('login.form.userName.errMsg') }]"
|
||||||
:validate-trigger="['change', 'blur']"
|
:validate-trigger="['change', 'blur']"
|
||||||
hide-label
|
hide-label
|
||||||
maxlength="64"
|
|
||||||
>
|
>
|
||||||
<a-input v-model="userInfo.username" :max-length="255" :placeholder="t('login.form.userName.placeholder')" />
|
<a-input
|
||||||
|
v-model="userInfo.username"
|
||||||
|
:max-length="64"
|
||||||
|
size="large"
|
||||||
|
:placeholder="t('login.form.userName.placeholder')"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
class="login-form-item"
|
class="login-form-item"
|
||||||
|
@ -41,18 +45,19 @@
|
||||||
v-model="userInfo.password"
|
v-model="userInfo.password"
|
||||||
:placeholder="t('login.form.password.placeholder')"
|
:placeholder="t('login.form.password.placeholder')"
|
||||||
allow-clear
|
allow-clear
|
||||||
maxlength="64"
|
:max-length="64"
|
||||||
|
size="large"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<div class="mb-6 mt-[12px]">
|
<div class="mb-[60px] mt-[12px]">
|
||||||
<a-button type="primary" html-type="submit" long :loading="loading">
|
<a-button type="primary" size="large" html-type="submit" long :loading="loading">
|
||||||
{{ t('login.form.login') }}
|
{{ t('login.form.login') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
<a-divider orientation="center" type="dashed">
|
<a-divider orientation="center" type="dashed" class="m-0 mb-2">
|
||||||
<span class="text-xs font-normal text-[var(--color-text-4)]">{{ t('login.form.modeLoginMethods') }}</span>
|
<span class="text-xs font-normal text-[var(--color-text-4)]">{{ t('login.form.modeLoginMethods') }}</span>
|
||||||
</a-divider>
|
</a-divider>
|
||||||
<div class="flex items-center justify-center">
|
<div class="mt-4 flex items-center justify-center">
|
||||||
<div v-if="userInfo.authenticate !== 'LDAP' && isShowLDAP" class="loginType" @click="switchLoginType('LDAP')">
|
<div v-if="userInfo.authenticate !== 'LDAP' && isShowLDAP" class="loginType" @click="switchLoginType('LDAP')">
|
||||||
<span class="type-text text-[10px]">LDAP</span>
|
<span class="type-text text-[10px]">LDAP</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -188,13 +193,6 @@
|
||||||
/* stylelint-disable color-function-notation */
|
/* stylelint-disable color-function-notation */
|
||||||
.login-form {
|
.login-form {
|
||||||
@apply flex flex-1 flex-col items-center justify-center;
|
@apply flex flex-1 flex-col items-center justify-center;
|
||||||
|
|
||||||
background: linear-gradient(
|
|
||||||
26.72deg,
|
|
||||||
rgba(var(--primary-5), 0.02) 0%,
|
|
||||||
rgba(var(--primary-5), 0.1) 51.67%,
|
|
||||||
var(--color-text-fff) 100%
|
|
||||||
);
|
|
||||||
.title-welcome {
|
.title-welcome {
|
||||||
color: rgb(var(--primary-5));
|
color: rgb(var(--primary-5));
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,6 +205,7 @@
|
||||||
selectable: !!hasAnyPermission(['PROJECT_USER:READ+DELETE', 'ORGANIZATION_MEMBER:READ+UPDATE']),
|
selectable: !!hasAnyPermission(['PROJECT_USER:READ+DELETE', 'ORGANIZATION_MEMBER:READ+UPDATE']),
|
||||||
showSetting: true,
|
showSetting: true,
|
||||||
heightUsed: 288,
|
heightUsed: 288,
|
||||||
|
showJumpMethod: true,
|
||||||
columns,
|
columns,
|
||||||
scroll: {
|
scroll: {
|
||||||
x: 1200,
|
x: 1200,
|
||||||
|
|
|
@ -47,18 +47,19 @@
|
||||||
value: TaskCenterEnum.API_SCENARIO,
|
value: TaskCenterEnum.API_SCENARIO,
|
||||||
label: t('project.taskCenter.apiScenario'),
|
label: t('project.taskCenter.apiScenario'),
|
||||||
},
|
},
|
||||||
{
|
// TODO 第一个版本目前不上以下几类
|
||||||
value: TaskCenterEnum.UI_TEST,
|
// {
|
||||||
label: t('project.taskCenter.uiDefaultFile'),
|
// value: TaskCenterEnum.UI_TEST,
|
||||||
},
|
// label: t('project.taskCenter.uiDefaultFile'),
|
||||||
{
|
// },
|
||||||
value: TaskCenterEnum.LOAD_TEST,
|
// {
|
||||||
label: t('project.taskCenter.performanceTest'),
|
// value: TaskCenterEnum.LOAD_TEST,
|
||||||
},
|
// label: t('project.taskCenter.performanceTest'),
|
||||||
{
|
// },
|
||||||
value: TaskCenterEnum.TEST_PLAN,
|
// {
|
||||||
label: t('project.taskCenter.testPlan'),
|
// value: TaskCenterEnum.TEST_PLAN,
|
||||||
},
|
// label: t('project.taskCenter.testPlan'),
|
||||||
|
// },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const timingTabList = ref([
|
const timingTabList = ref([
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
:placeholder="t('system.orgTemplate.templateNamePlaceholder')"
|
:placeholder="t('system.orgTemplate.templateNamePlaceholder')"
|
||||||
:max-length="255"
|
:max-length="255"
|
||||||
class="max-w-[732px]"
|
class="max-w-[732px]"
|
||||||
|
:disabled="templateForm?.internal"
|
||||||
></a-input>
|
></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item field="remark" :label="t('system.orgTemplate.description')" asterisk-position="end">
|
<a-form-item field="remark" :label="t('system.orgTemplate.description')" asterisk-position="end">
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<MsCard has-breadcrumb simple>
|
<MsCard has-breadcrumb simple>
|
||||||
<div class="mb-4 flex items-center justify-between">
|
<div class="mb-4 flex items-center justify-between">
|
||||||
<span v-if="isEnableOrdTemplate" class="font-medium">{{ t('system.orgTemplate.templateList') }}</span>
|
<!-- <span v-if="isEnableOrdTemplate" class="font-medium">{{
|
||||||
|
t('system.orgTemplate.templateList', { type: getTemplateName('project', route.query.type as string) })
|
||||||
|
}}</span> -->
|
||||||
|
<span v-if="isShowList" class="font-medium">{{
|
||||||
|
t('system.orgTemplate.templateList', { type: getTemplateName('project', route.query.type as string) })
|
||||||
|
}}</span>
|
||||||
<!--TODO 这个版本不允许修改默认模版也不允许创建用例模版 -->
|
<!--TODO 这个版本不允许修改默认模版也不允许创建用例模版 -->
|
||||||
<a-button
|
<a-button
|
||||||
v-if="!isEnableOrdTemplate && route.query.type === 'BUG'"
|
v-if="!isEnableOrdTemplate && route.query.type === 'BUG'"
|
||||||
|
@ -10,7 +15,11 @@
|
||||||
:disabled="false"
|
:disabled="false"
|
||||||
@click="createTemplate"
|
@click="createTemplate"
|
||||||
>
|
>
|
||||||
{{ t('system.orgTemplate.createTemplate') }}
|
{{
|
||||||
|
t('system.orgTemplate.createTemplateType', {
|
||||||
|
type: getTemplateName('project', route.query.type as string),
|
||||||
|
})
|
||||||
|
}}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-input-search
|
<a-input-search
|
||||||
v-model:model-value="keyword"
|
v-model:model-value="keyword"
|
||||||
|
@ -33,7 +42,7 @@
|
||||||
<!-- TODO 这个版本不允许修改默认模版也不允许创建用例模版 -->
|
<!-- TODO 这个版本不允许修改默认模版也不允许创建用例模版 -->
|
||||||
<a-switch
|
<a-switch
|
||||||
v-model="record.enableDefault"
|
v-model="record.enableDefault"
|
||||||
:disabled="true"
|
:disabled="record.enableDefault || isEnableOrdTemplate"
|
||||||
size="small"
|
size="small"
|
||||||
type="line"
|
type="line"
|
||||||
@change="(value) => changeDefault(value, record)"
|
@change="(value) => changeDefault(value, record)"
|
||||||
|
@ -55,9 +64,12 @@
|
||||||
<MsButton v-permission="['PROJECT_TEMPLATE:READ+UPDATE']" @click="editTemplate(record.id)">{{
|
<MsButton v-permission="['PROJECT_TEMPLATE:READ+UPDATE']" @click="editTemplate(record.id)">{{
|
||||||
t('system.orgTemplate.edit')
|
t('system.orgTemplate.edit')
|
||||||
}}</MsButton>
|
}}</MsButton>
|
||||||
<MsButton v-permission="['PROJECT_TEMPLATE:READ+ADD']" class="!mr-0" @click="copyTemplate(record.id)">{{
|
<MsButton
|
||||||
t('system.orgTemplate.copy')
|
v-if="route.query.type === 'BUG' && hasAnyPermission(['PROJECT_TEMPLATE:READ+ADD'])"
|
||||||
}}</MsButton>
|
class="!mr-0"
|
||||||
|
@click="copyTemplate(record.id)"
|
||||||
|
>{{ t('system.orgTemplate.copy') }}</MsButton
|
||||||
|
>
|
||||||
<a-divider
|
<a-divider
|
||||||
v-if="!record.internal"
|
v-if="!record.internal"
|
||||||
v-permission="['PROJECT_TEMPLATE:READ+ADD']"
|
v-permission="['PROJECT_TEMPLATE:READ+ADD']"
|
||||||
|
@ -130,6 +142,7 @@
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getCustomDetailFields,
|
getCustomDetailFields,
|
||||||
|
getTemplateName,
|
||||||
getTotalFieldOptionList,
|
getTotalFieldOptionList,
|
||||||
} from '@/views/setting/organization/template/components/fieldSetting';
|
} from '@/views/setting/organization/template/components/fieldSetting';
|
||||||
|
|
||||||
|
@ -203,10 +216,11 @@
|
||||||
const { propsRes, propsEvent, loadList, setLoadListParams, setProps } = useTable(getProjectTemplateList, {
|
const { propsRes, propsEvent, loadList, setLoadListParams, setProps } = useTable(getProjectTemplateList, {
|
||||||
tableKey: TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT,
|
tableKey: TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||||
scroll: { x: '1400px' },
|
scroll: { x: '1400px' },
|
||||||
|
columns: fieldColumns,
|
||||||
selectable: false,
|
selectable: false,
|
||||||
noDisable: true,
|
noDisable: true,
|
||||||
size: 'default',
|
size: 'default',
|
||||||
showSetting: true,
|
showSetting: false,
|
||||||
showPagination: false,
|
showPagination: false,
|
||||||
heightUsed: 380,
|
heightUsed: 380,
|
||||||
});
|
});
|
||||||
|
@ -376,6 +390,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isShowList = computed(() => {
|
||||||
|
if (!hasAnyPermission(['PROJECT_TEMPLATE:READ+ADD'])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (isEnableOrdTemplate.value && route.query.type === 'BUG') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return route.query.type !== 'BUG';
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchData();
|
fetchData();
|
||||||
updateColumns();
|
updateColumns();
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<TemplateItem
|
<TemplateItem
|
||||||
:card-item="item"
|
:card-item="item"
|
||||||
:index="index"
|
:index="index"
|
||||||
mode="organization"
|
mode="project"
|
||||||
@field-setting="fieldSetting"
|
@field-setting="fieldSetting"
|
||||||
@template-management="templateManagement"
|
@template-management="templateManagement"
|
||||||
@workflow-setup="workflowSetup"
|
@workflow-setup="workflowSetup"
|
||||||
|
|
|
@ -238,10 +238,11 @@
|
||||||
getMemberList,
|
getMemberList,
|
||||||
{
|
{
|
||||||
tableKey: TableKeyEnum.ORGANIZATION_MEMBER,
|
tableKey: TableKeyEnum.ORGANIZATION_MEMBER,
|
||||||
scroll: { x: 1800 },
|
scroll: { x: 1600 },
|
||||||
selectable: !!hasAnyPermission(['ORGANIZATION_MEMBER:READ+ADD', 'ORGANIZATION_MEMBER:READ+ADD']),
|
selectable: !!hasAnyPermission(['ORGANIZATION_MEMBER:READ+ADD', 'ORGANIZATION_MEMBER:READ+ADD']),
|
||||||
heightUsed: 288,
|
heightUsed: 288,
|
||||||
showSetting: true,
|
showSetting: true,
|
||||||
|
showJumpMethod: true,
|
||||||
size: 'default',
|
size: 'default',
|
||||||
},
|
},
|
||||||
(record) => {
|
(record) => {
|
||||||
|
|
|
@ -12,12 +12,7 @@
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
<div class="flex w-[100%] flex-row justify-between text-sm font-normal">
|
<div class="flex w-[100%] flex-row justify-between text-sm font-normal">
|
||||||
<div
|
<div v-for="(item, index) in cardContent" :key="item.id" class="item mt-4" :class="`ms-item-${index}`">
|
||||||
v-for="(item, index) in cardContent"
|
|
||||||
:key="item.id"
|
|
||||||
class="item mt-4 p-[16px]"
|
|
||||||
:class="`ms-item-${index}`"
|
|
||||||
>
|
|
||||||
<span class="mr-3">
|
<span class="mr-3">
|
||||||
<svg-icon width="64px" height="46px" :name="item.icon" />
|
<svg-icon width="64px" height="46px" :name="item.icon" />
|
||||||
</span>
|
</span>
|
||||||
|
@ -163,6 +158,7 @@
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
.item {
|
.item {
|
||||||
|
padding: 16px;
|
||||||
width: calc(50% - 10px);
|
width: calc(50% - 10px);
|
||||||
height: 78px;
|
height: 78px;
|
||||||
border: 1px solid #ffffff;
|
border: 1px solid #ffffff;
|
||||||
|
@ -170,9 +166,11 @@
|
||||||
@apply flex items-center rounded-md;
|
@apply flex items-center rounded-md;
|
||||||
}
|
}
|
||||||
.ms-item-0 {
|
.ms-item-0 {
|
||||||
background: url('@/assets/images/ms_plugindownload.jpg') no-repeat center / auto;
|
background: url('@/assets/images/ms_plugindownload.jpg') no-repeat center;
|
||||||
|
background-size: cover;
|
||||||
}
|
}
|
||||||
.ms-item-1 {
|
.ms-item-1 {
|
||||||
background: url('@/assets/images/ms_configplugin.jpg') no-repeat center / auto;
|
background: url('@/assets/images/ms_configplugin.jpg') no-repeat center;
|
||||||
|
background-size: cover;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
@success="okHandler"
|
@success="okHandler"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<a-button class="mt-1 px-0" type="text" :disabled="totalData.length > 20" @click="createField">
|
<a-button class="mt-1 px-0" type="text" :disabled="totalData.length >= 20" @click="createField">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-plus class="text-[14px]" />
|
<icon-plus class="text-[14px]" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -7,13 +7,7 @@
|
||||||
}}</a-alert>
|
}}</a-alert>
|
||||||
<div class="mb-4 flex items-center justify-between">
|
<div class="mb-4 flex items-center justify-between">
|
||||||
<span v-if="isEnabledTemplate" class="font-medium">{{ t('system.orgTemplate.fieldList') }}</span>
|
<span v-if="isEnabledTemplate" class="font-medium">{{ t('system.orgTemplate.fieldList') }}</span>
|
||||||
<a-button
|
<a-button v-permission="props.createPermission" type="primary" :disabled="isDisabled" @click="fieldHandler">
|
||||||
v-else
|
|
||||||
v-permission="props.createPermission"
|
|
||||||
type="primary"
|
|
||||||
:disabled="isDisabled"
|
|
||||||
@click="fieldHandler"
|
|
||||||
>
|
|
||||||
{{ t('system.orgTemplate.addField') }}
|
{{ t('system.orgTemplate.addField') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-input-search
|
<a-input-search
|
||||||
|
@ -274,7 +268,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDisabled = computed(() => {
|
const isDisabled = computed(() => {
|
||||||
return totalData.value.length > 20;
|
return totalData.value.length >= 20;
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
:placeholder="t('system.orgTemplate.templateNamePlaceholder')"
|
:placeholder="t('system.orgTemplate.templateNamePlaceholder')"
|
||||||
:max-length="255"
|
:max-length="255"
|
||||||
class="max-w-[732px]"
|
class="max-w-[732px]"
|
||||||
|
:disabled="templateForm?.internal"
|
||||||
></a-input>
|
></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item field="remark" :label="t('system.orgTemplate.description')" asterisk-position="end">
|
<a-form-item field="remark" :label="t('system.orgTemplate.description')" asterisk-position="end">
|
||||||
|
|
|
@ -25,13 +25,13 @@
|
||||||
<span v-if="props.cardItem.key === 'BUG'" class="operation hover:text-[rgb(var(--primary-5))]">
|
<span v-if="props.cardItem.key === 'BUG'" class="operation hover:text-[rgb(var(--primary-5))]">
|
||||||
<span @click="workflowSetup">{{ t('system.orgTemplate.workflowSetup') }}</span>
|
<span @click="workflowSetup">{{ t('system.orgTemplate.workflowSetup') }}</span>
|
||||||
<a-divider
|
<a-divider
|
||||||
v-if="isEnableProject && props.cardItem.key === 'BUG'"
|
v-if="hasEnablePermission && props.mode === 'organization' && isEnableProject"
|
||||||
v-permission="['ORGANIZATION_TEMPLATE:READ+ENABLE']"
|
v-permission="['ORGANIZATION_TEMPLATE:READ+ENABLE']"
|
||||||
direction="vertical"
|
direction="vertical"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-if="isEnableProject && hasEnablePermission"
|
v-if="hasEnablePermission && props.mode === 'organization' && isEnableProject"
|
||||||
class="rounded p-[2px] hover:bg-[rgb(var(--primary-9))]"
|
class="rounded p-[2px] hover:bg-[rgb(var(--primary-9))]"
|
||||||
>
|
>
|
||||||
<MsTableMoreAction :list="moreActions" @select="handleMoreActionSelect"
|
<MsTableMoreAction :list="moreActions" @select="handleMoreActionSelect"
|
||||||
|
|
|
@ -4,7 +4,12 @@
|
||||||
t('system.orgTemplate.enableTemplateTip')
|
t('system.orgTemplate.enableTemplateTip')
|
||||||
}}</a-alert>
|
}}</a-alert>
|
||||||
<div class="mb-4 flex items-center justify-between">
|
<div class="mb-4 flex items-center justify-between">
|
||||||
<span v-if="isEnableOrdTemplate" class="font-medium">{{ t('system.orgTemplate.templateList') }}</span>
|
<!-- <span v-if="isEnableOrdTemplate || route.query.type === 'BUG'" class="font-medium">{{
|
||||||
|
t('system.orgTemplate.templateList', { type: getTemplateName('organization', route.query.type as string) })
|
||||||
|
}}</span> -->
|
||||||
|
<span v-if="isShowListTip" class="font-medium">{{
|
||||||
|
t('system.orgTemplate.templateList', { type: getTemplateName('organization', route.query.type as string) })
|
||||||
|
}}</span>
|
||||||
<a-button
|
<a-button
|
||||||
v-if="!isEnableOrdTemplate && route.query.type === 'BUG'"
|
v-if="!isEnableOrdTemplate && route.query.type === 'BUG'"
|
||||||
v-permission="['ORGANIZATION_TEMPLATE:READ+ADD']"
|
v-permission="['ORGANIZATION_TEMPLATE:READ+ADD']"
|
||||||
|
@ -12,7 +17,11 @@
|
||||||
:disabled="false"
|
:disabled="false"
|
||||||
@click="createTemplate"
|
@click="createTemplate"
|
||||||
>
|
>
|
||||||
{{ t('system.orgTemplate.createTemplate') }}
|
{{
|
||||||
|
t('system.orgTemplate.createTemplateType', {
|
||||||
|
type: getTemplateName('organization', route.query.type as string),
|
||||||
|
})
|
||||||
|
}}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-input-search
|
<a-input-search
|
||||||
v-model:model-value="keyword"
|
v-model:model-value="keyword"
|
||||||
|
@ -38,9 +47,12 @@
|
||||||
<MsButton v-permission="['ORGANIZATION_TEMPLATE:READ+UPDATE']" @click="editTemplate(record.id)">{{
|
<MsButton v-permission="['ORGANIZATION_TEMPLATE:READ+UPDATE']" @click="editTemplate(record.id)">{{
|
||||||
t('system.orgTemplate.edit')
|
t('system.orgTemplate.edit')
|
||||||
}}</MsButton>
|
}}</MsButton>
|
||||||
<MsButton v-permission="['ORGANIZATION_TEMPLATE:READ+ADD']" class="!mr-0" @click="copyTemplate(record.id)">{{
|
<MsButton
|
||||||
t('system.orgTemplate.copy')
|
v-if="route.query.type === 'BUG' && hasAnyPermission(['ORGANIZATION_TEMPLATE:READ+ADD'])"
|
||||||
}}</MsButton>
|
class="!mr-0"
|
||||||
|
@click="copyTemplate(record.id)"
|
||||||
|
>{{ t('system.orgTemplate.copy') }}</MsButton
|
||||||
|
>
|
||||||
<a-divider
|
<a-divider
|
||||||
v-if="!record.internal"
|
v-if="!record.internal"
|
||||||
v-permission="['ORGANIZATION_TEMPLATE:READ+ADD']"
|
v-permission="['ORGANIZATION_TEMPLATE:READ+ADD']"
|
||||||
|
@ -89,6 +101,8 @@
|
||||||
import { SettingRouteEnum } from '@/enums/routeEnum';
|
import { SettingRouteEnum } from '@/enums/routeEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
|
import { getTemplateName } from '@/views/setting/organization/template/components/fieldSetting';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const tableStore = useTableStore();
|
const tableStore = useTableStore();
|
||||||
|
@ -145,10 +159,11 @@
|
||||||
const { propsRes, propsEvent, loadList, setLoadListParams, setProps } = useTable(getOrganizeTemplateList, {
|
const { propsRes, propsEvent, loadList, setLoadListParams, setProps } = useTable(getOrganizeTemplateList, {
|
||||||
tableKey: TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT,
|
tableKey: TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||||
scroll: { x: '100%' },
|
scroll: { x: '100%' },
|
||||||
|
columns: fieldColumns,
|
||||||
selectable: false,
|
selectable: false,
|
||||||
noDisable: true,
|
noDisable: true,
|
||||||
size: 'default',
|
size: 'default',
|
||||||
showSetting: true,
|
showSetting: false,
|
||||||
showPagination: false,
|
showPagination: false,
|
||||||
heightUsed: 380,
|
heightUsed: 380,
|
||||||
});
|
});
|
||||||
|
@ -279,11 +294,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isShowListTip = computed(() => {
|
||||||
|
if (!hasAnyPermission(['ORGANIZATION_TEMPLATE:READ+ADD'])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (isEnableOrdTemplate.value && route.query.type === 'BUG') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return route.query.type !== 'BUG';
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchData();
|
fetchData();
|
||||||
updateColumns();
|
updateColumns();
|
||||||
});
|
});
|
||||||
tableStore.initColumn(TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT, fieldColumns, 'drawer');
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|
|
@ -240,7 +240,7 @@
|
||||||
(val) => {
|
(val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
selectList.value = val as DefinedFieldItem[];
|
selectList.value = val as DefinedFieldItem[];
|
||||||
setProps({ data: selectList.value });
|
setProps({ data: val });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default {
|
||||||
'system.orgTemplate.defaultValue': 'Default value',
|
'system.orgTemplate.defaultValue': 'Default value',
|
||||||
'system.orgTemplate.required': 'Required',
|
'system.orgTemplate.required': 'Required',
|
||||||
'system.orgTemplate.enableTemplateTip': 'The project template is enabled. The organization template is unavailable',
|
'system.orgTemplate.enableTemplateTip': 'The project template is enabled. The organization template is unavailable',
|
||||||
'system.orgTemplate.templateList': 'Template list',
|
'system.orgTemplate.templateList': ' {type} list',
|
||||||
'system.orgTemplate.createTemplate': 'Create',
|
'system.orgTemplate.createTemplate': 'Create',
|
||||||
'system.orgTemplate.templatePreview': 'Template preview',
|
'system.orgTemplate.templatePreview': 'Template preview',
|
||||||
'system.orgTemplate.templateName': 'Template name',
|
'system.orgTemplate.templateName': 'Template name',
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default {
|
||||||
'system.orgTemplate.defaultValue': '默认值',
|
'system.orgTemplate.defaultValue': '默认值',
|
||||||
'system.orgTemplate.required': '是否必填',
|
'system.orgTemplate.required': '是否必填',
|
||||||
'system.orgTemplate.enableTemplateTip': '已启用项目模板,组织模板不可操作',
|
'system.orgTemplate.enableTemplateTip': '已启用项目模板,组织模板不可操作',
|
||||||
'system.orgTemplate.templateList': '模板列表',
|
'system.orgTemplate.templateList': ' {type}列表',
|
||||||
'system.orgTemplate.createTemplate': '创建模板',
|
'system.orgTemplate.createTemplate': '创建模板',
|
||||||
'system.orgTemplate.templatePreview': '模板预览',
|
'system.orgTemplate.templatePreview': '模板预览',
|
||||||
'system.orgTemplate.templateName': '模板名称',
|
'system.orgTemplate.templateName': '模板名称',
|
||||||
|
|
|
@ -87,6 +87,7 @@
|
||||||
:auto-upload="false"
|
:auto-upload="false"
|
||||||
:disabled="confirmLoading"
|
:disabled="confirmLoading"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
|
:file-type-tip="t('system.plugin.supportFormatType')"
|
||||||
></MsUpload>
|
></MsUpload>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
|
|
@ -111,4 +111,5 @@ export default {
|
||||||
'system.plugin.switchAllOrganizeTip': 'The plugin will be visible to all organizations',
|
'system.plugin.switchAllOrganizeTip': 'The plugin will be visible to all organizations',
|
||||||
'system.plugin.switchSectionOrganizeTip': 'Plug-in to specify organization is visible',
|
'system.plugin.switchSectionOrganizeTip': 'Plug-in to specify organization is visible',
|
||||||
'system.plugin.changeOrganizeTip': 'Changing the organization will make historical data unavailable, so be careful!',
|
'system.plugin.changeOrganizeTip': 'Changing the organization will make historical data unavailable, so be careful!',
|
||||||
|
'system.plugin.supportFormatType': 'Only supports the JAR file format',
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,4 +90,5 @@ export default {
|
||||||
'system.plugin.switchAllOrganizeTip': '插件将对所有组织可见',
|
'system.plugin.switchAllOrganizeTip': '插件将对所有组织可见',
|
||||||
'system.plugin.switchSectionOrganizeTip': '插件将对指定组织可见',
|
'system.plugin.switchSectionOrganizeTip': '插件将对指定组织可见',
|
||||||
'system.plugin.changeOrganizeTip': ' 变更组织会导致历史数据不可用,请谨慎操作!',
|
'system.plugin.changeOrganizeTip': ' 变更组织会导致历史数据不可用,请谨慎操作!',
|
||||||
|
'system.plugin.supportFormatType': '仅支持JAR格式的文件',
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<MsCard simple no-content-padding>
|
||||||
|
<TaskCenter group="system" />
|
||||||
|
</MsCard>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
|
import TaskCenter from '@/views/project-management/taskCenter/component/taskCom.vue';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.box {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
.left {
|
||||||
|
padding: 24px;
|
||||||
|
width: 252px;
|
||||||
|
height: 100%;
|
||||||
|
border-right: 1px solid var(--color-text-n8);
|
||||||
|
.item {
|
||||||
|
padding: 0 20px;
|
||||||
|
height: 38px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 38px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
&.active {
|
||||||
|
background: rgb(var(--primary-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
width: calc(100% - 300px);
|
||||||
|
flex-grow: 1; /* 自适应 */
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.no-content {
|
||||||
|
:deep(.arco-tabs-content) {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue