fix(项目设置): 缺陷模板跨项目复制问题

--bug=1018327 --user=宋昌昌 【项目设置】模版管理-所有模版没有跨项目复制功能 https://www.tapd.cn/55049933/s/1265892

Co-authored-by: song-cc-rock <changchang.song@fit2cloud.com>
This commit is contained in:
MeterSphere Bot 2022-10-18 15:00:07 +08:00 committed by GitHub
parent 9250d0be63
commit edbbed011b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 146 additions and 6 deletions

View File

@ -55,3 +55,11 @@ export function deleteApiFieldTemplateById(id) {
export function getFieldTemplateApiOption(projectId) {
return get(`/field/template/api/option/${projectId}`);
}
export function getIssueTemplateCopyProject(userId, workspaceId) {
return get(`/field/template/issue/get/copy/project/` + userId + `/` + workspaceId);
}
export function copyIssueTemplate(param) {
return post(`/field/template/issue/copy`, param);
}

View File

@ -85,6 +85,7 @@ export function LOG_MODULE_MAP(_this) {
['PROJECT_ENVIRONMENT_SETTING', _this.$t('operating_log.project_environment_setting')],
['PROJECT_PROJECT_MANAGER', _this.$t('operating_log.project_project_manager')],
['PROJECT_FILE_MANAGEMENT', _this.$t('operating_log.project_file_management')],
['PROJECT_TEMPLATE_MANAGEMENT', _this.$t('operating_log.project_template_management')],
['PROJECT_PROJECT_MEMBER', _this.$t('operating_log.project_project_member')],
['PERSONAL_INFORMATION_PERSONAL_SETTINGS', _this.$t('operating_log.personal_information_personal_settings')],
['PERSONAL_INFORMATION_APIKEYS', _this.$t('operating_log.personal_information_apikeys')],

View File

@ -0,0 +1,131 @@
<template>
<el-dialog :title="$t('custom_field.copy_issue_template')" :visible.sync="showDialog" :close-on-click-modal="false">
<span style="font-size:13px; margin-left: 10px">{{$t('custom_field.copy_issue_template_tips1')}}</span>
<span style="font-size:13px; margin-left: 10px; color:red">{{$t('custom_field.copy_issue_template_tips2')}}</span>
<el-divider></el-divider>
<span style="font-size:13px; margin-left: 10px">{{$t('custom_field.copy_issue_template_model_tips1')}}</span>
<i style="font-size: 12px">{{$t('custom_field.copy_issue_template_model_tips2')}}</i>
<el-checkbox-group v-model="copyModelVal" @change="checkModelChanged" style="margin-top: 15px">
<el-checkbox false-label="0" true-label="0" :label="$t('custom_field.copy_issue_template_model_append')" style="margin-left: 10px"></el-checkbox>
<el-checkbox false-label="1" true-label="1" :label="$t('custom_field.copy_issue_template_model_cover')" style="margin-left: 25px"></el-checkbox>
</el-checkbox-group>
<div class="copyTargetProjectTree" style="margin-top: 20px; margin-left: 10px">
<span>{{$t('custom_field.target_project')}}</span>
<el-tree
class="copyProjectTree"
ref="tree"
:data="copyProjects"
:props="defaultProps"
:show-checkbox="true"
:default-expand-all="true"
:check-on-click-node="true"
:expand-on-click-node="false"
node-key="id">
<span slot-scope="{data}">
<span>{{ data.name }}</span>
<span v-if="data.id === copyData.projectId" style="font-size: 12px">{{$t("custom_field.current_project")}}</span>
<span v-if="data.customPermissionFlag == null || !data.customPermissionFlag" style="font-size: 12px; color: red;">{{$t("custom_field.no_custom_fields_permission")}}</span>
</span>
</el-tree>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="showDialog = false" size="small">{{ $t('test_track.cancel') }}</el-button>
<el-button type="primary" @click="confirm" size="small">{{ $t('test_track.confirm') }}</el-button>
</div>
</el-dialog>
</template>
<script>
import draggable from 'vuedraggable';
import TemplateComponentEditHeader from "@/business/menu/template/ext/TemplateComponentEditHeader";
import MsFormDivider from "metersphere-frontend/src/components/MsFormDivider";
import {ISSUE_PLATFORM_OPTION} from "metersphere-frontend/src/utils/table-constants";
import CustomFieldFormList from "@/business/menu/template/CustomFieldFormList";
import CustomFieldRelateList from "@/business/menu/template/CustomFieldRelateList";
import FieldTemplateEdit from "@/business/menu/template/FieldTemplateEdit";
import FormRIchTextItem from "metersphere-frontend/src/components/FormRichTextItem";
import {LOCAL} from "metersphere-frontend/src/utils/constants";
import {getUUID} from "metersphere-frontend/src/utils";
import {getCurrentUserId, getCurrentWorkspaceId} from "metersphere-frontend/src/utils/token"
import {copyIssueTemplate, getIssueTemplateCopyProject} from "@/api/template";
export default {
name: "IssueTemplateCopy",
data() {
return {
root: null,
showDialog: false,
copyData: null,
copyProjects: [],
copyModelVal: "0",
defaultProps: {
children: 'children',
label: 'name',
disabled: (data, node) => {
return data.customPermissionFlag ? !data.customPermissionFlag : true;
}
}
};
},
computed: {
},
methods: {
open(copyData) {
this.root = null;
this.copyProjects = [];
this.copyModelVal = "0";
this.showDialog = true;
this.copyData = copyData;
this.initCopyProjects();
},
checkModelChanged(val) {
if (val !== "null") {
this.copyModelVal = this.copyModelVal !== val ? val : this.copyModelVal;
}
},
initCopyProjects() {
let issueTemplateId = this.copyData.id;
getIssueTemplateCopyProject(getCurrentUserId(), getCurrentWorkspaceId())
.then((response) => {
this.root = {id: getUUID(), name: response.data.workspaceName, customPermissionFlag: true, children: response.data.projectDTOS};
this.copyProjects.push(this.root)
})
},
confirm() {
let checkProjectIds = this.$refs.tree.getCheckedKeys();
if (checkProjectIds.find(item => item === this.root.id)) {
checkProjectIds.splice(checkProjectIds.findIndex(item => item === this.root.id), 1)
}
let param = {id: this.copyData.id, copyModel: this.copyModelVal, targetProjectIds: checkProjectIds}
copyIssueTemplate(param)
.then((response) => {
this.showDialog = false;
this.$emit('refresh');
this.$message({
type: 'success',
message: this.$t('commons.copy_success'),
});
})
}
}
};
</script>
<style scoped>
:deep(.el-dialog__body) {
padding: 10px 20px!important;
}
.copyProjectTree {
margin-top: 10px;
height: 200px;
overflow: auto;
display: flex
}
:deep(.el-tree-node.is-checked > .el-tree-node__content) {
color: #783887;
}
</style>

View File

@ -75,6 +75,7 @@
:page-size.sync="pageSize"
:total="total"/>
<issue-template-copy ref="templateCopy" @refresh="initTableData"/>
<issue-template-edit ref="templateEdit" @refresh="initTableData"/>
<ms-delete-confirm :title="$t('commons.template_delete')" @delete="_handleDelete" ref="deleteConfirm"/>
</el-card>
@ -93,11 +94,13 @@ import MsTable from "metersphere-frontend/src/components/table/MsTable";
import IssueTemplateEdit from "./IssueTemplateEdit";
import {deleteIssueFieldTemplateById, getIssueFieldTemplatePages} from "../../../api/template";
import MsDeleteConfirm from "metersphere-frontend/src/components/MsDeleteConfirm";
import IssueTemplateCopy from "./IssueTemplateCopy";
export default {
name: "IssuesTemplateList",
components: {
IssueTemplateEdit,
IssueTemplateCopy,
MsTableHeader,
MsTablePagination, MsTableButton, MsTableOperators, MsTableColumn, MsTable , MsDeleteConfirm
},
@ -123,12 +126,10 @@ export default {
exec: this.handleEdit
}, {
tip: this.$t('commons.copy'), icon: "el-icon-copy-document", type: "success",
exec: this.handleCopy,
isDisable: this.systemDisable
exec: this.handleCopy
}, {
tip: this.$t('commons.delete'), icon: "el-icon-delete", type: "danger",
exec: this.handleDelete,
isDisable: this.systemDisable
exec: this.handleDelete
}
],
};
@ -169,8 +170,7 @@ export default {
handleCopy(data) {
let copyData = {};
Object.assign(copyData, data);
copyData.name = data.name + '_copy';
this.$refs.templateEdit.open(copyData, true);
this.$refs.templateCopy.open(copyData);
},
handleDelete(data) {
this.$refs.deleteConfirm.open(data);