refactor(项目管理): 文件管理对接Git仓库部分开源

--task=1010911 --user=宋天阳
【开源计划】文件管理支持对接第三方仓库
https://www.tapd.cn/55049933/s/1327957
This commit is contained in:
song-tianyang 2023-01-17 14:31:05 +08:00 committed by fit2-zhao
parent c12064275f
commit 2e0b010fe2
4 changed files with 288 additions and 180 deletions

View File

@ -35,7 +35,7 @@ public class FileRepositoryController {
GitRepositoryUtil utils = new GitRepositoryUtil(node.getRepositoryPath(), node.getRepositoryUserName(), node.getRepositoryToken());
utils.getBranches();
}
return "suucess";
return "success";
}
@GetMapping(value = "/fileVersion/{refId}")

View File

@ -1,41 +1,68 @@
<template>
<el-dialog :title="dialogTitle"
:visible.sync="dialogFormVisible"
:before-close="close"
width="600px">
<el-row v-show="operationType==='create'" type="flex" justify="center" style="margin-bottom: 10px;">
<el-dialog
:title="dialogTitle"
:visible.sync="dialogFormVisible"
:before-close="close"
width="600px"
>
<el-row
v-show="operationType === 'create'"
type="flex"
justify="center"
style="margin-bottom: 10px"
>
<el-radio-group v-model="moduleForm.moduleType">
<el-radio label="module">{{ $t("project.project_file.file_module_type.module") }}</el-radio>
<el-radio v-xpack label="repository">{{ $t("project.project_file.file_module_type.repository") }}</el-radio>
<el-radio label="module">{{
$t("project.project_file.file_module_type.module")
}}</el-radio>
<el-radio label="repository">{{
$t("project.project_file.file_module_type.repository")
}}</el-radio>
</el-radio-group>
</el-row>
<el-form :model="moduleForm" :rules="moduleRule" ref="form" label-width="100px" @submit.native.prevent>
<el-form-item v-if="moduleForm.moduleType === 'module'"
:label="$t('test_track.module.name')"
prop="name">
<el-form
:model="moduleForm"
:rules="moduleRule"
ref="form"
label-width="100px"
@submit.native.prevent
>
<el-form-item
v-if="moduleForm.moduleType === 'module'"
:label="$t('test_track.module.name')"
prop="name"
>
<el-input v-model="moduleForm.name"></el-input>
</el-form-item>
<div v-if="moduleForm.moduleType === 'repository'">
<el-form-item
:label="$t('project.project_file.repository.name')"
prop="name">
prop="name"
>
<el-input v-model="moduleForm.name"></el-input>
</el-form-item>
<el-form-item
:label="$t('project.project_file.repository.path')"
prop="repositoryPath">
prop="repositoryPath"
>
<el-input v-model="moduleForm.repositoryPath"></el-input>
</el-form-item>
<el-form-item
:label="$t('api_test.request.tcp.username')"
prop="repositoryUserName">
prop="repositoryUserName"
>
<el-input v-model="moduleForm.repositoryUserName">
<template slot="append">
<el-tooltip class="item" effect="dark"
:content="$t('project.project_file.validation.input_gitee_user_please')" placement="top">
<i class="el-icon-info"/>
<el-tooltip
class="item"
effect="dark"
:content="
$t('project.project_file.validation.input_gitee_user_please')
"
placement="top"
>
<i class="el-icon-info" />
</el-tooltip>
</template>
</el-input>
@ -43,13 +70,18 @@
<el-form-item
:label="$t('project.project_file.repository.token')"
prop="repositoryToken">
<el-input show-password v-model="moduleForm.repositoryToken"></el-input>
prop="repositoryToken"
>
<el-input
show-password
v-model="moduleForm.repositoryToken"
></el-input>
</el-form-item>
<el-form-item
type="textarea"
:label="$t('project.project_file.repository.desc')"
prop="repositoryDesc">
prop="repositoryDesc"
>
<el-input v-model="moduleForm.repositoryDesc"></el-input>
</el-form-item>
</div>
@ -57,15 +89,25 @@
<template v-slot:footer>
<div class="dialog-footer">
<el-button @click="close">{{ $t('commons.cancel') }}</el-button>
<el-button v-prevent-re-click :loading="isConnBtnLoading" type="primary" @click="testConnect"
v-show="moduleForm.moduleType === 'repository'"
@keydown.enter.native.prevent>
{{ $t('system_parameter_setting.test_connection') }}
<el-button @click="close">{{ $t("commons.cancel") }}</el-button>
<el-button
v-prevent-re-click
:loading="isConnBtnLoading"
type="primary"
@click="testConnect"
v-show="moduleForm.moduleType === 'repository'"
@keydown.enter.native.prevent
>
{{ $t("system_parameter_setting.test_connection") }}
</el-button>
<el-button v-prevent-re-click :loading="isSaveBtnLoading" type="primary" @click="saveFileModule"
@keydown.enter.native.prevent>
{{ $t('commons.confirm') }}
<el-button
v-prevent-re-click
:loading="isSaveBtnLoading"
type="primary"
@click="saveFileModule"
@keydown.enter.native.prevent
>
{{ $t("commons.confirm") }}
</el-button>
</div>
</template>
@ -73,10 +115,17 @@
</template>
<script>
import {listenGoBack, removeGoBackListener} from "metersphere-frontend/src/utils";
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
import {
listenGoBack,
removeGoBackListener,
} from "metersphere-frontend/src/utils";
import { getCurrentProjectID } from "metersphere-frontend/src/utils/token";
import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter";
import {createFileModule, modifyFileModule, testConnectRepository} from "@/api/file";
import {
createFileModule,
modifyFileModule,
testConnectRepository,
} from "@/api/file";
export default {
name: "FileModuleDialog",
@ -86,66 +135,104 @@ export default {
data() {
return {
dialogFormVisible: false,
dialogTitle: '',
operationType: '',
dialogTitle: "",
operationType: "",
projectId: getCurrentProjectID(),
isConnBtnLoading: false,
isSaveBtnLoading: false,
moduleForm: {
name: '',
moduleType: 'module',
repositoryUserName: '',
repositoryPath: '',
repositoryToken: '',
repositoryDesc: '',
name: "",
moduleType: "module",
repositoryUserName: "",
repositoryPath: "",
repositoryToken: "",
repositoryDesc: "",
},
moduleRule: {
name: [
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
{max: 60, message: this.$t('test_track.length_less_than') + '60', trigger: 'blur'}
{
required: true,
message: this.$t("test_track.case.input_name"),
trigger: "blur",
},
{
max: 60,
message: this.$t("test_track.length_less_than") + "60",
trigger: "blur",
},
],
},
}
};
},
watch: {
'moduleForm.moduleType'() {
if (this.moduleForm.moduleType === 'module') {
"moduleForm.moduleType"() {
if (this.moduleForm.moduleType === "module") {
this.moduleRule = {
name: [
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
{max: 60, message: this.$t('test_track.length_less_than') + '60', trigger: 'blur'}
{
required: true,
message: this.$t("test_track.case.input_name"),
trigger: "blur",
},
{
max: 60,
message: this.$t("test_track.length_less_than") + "60",
trigger: "blur",
},
],
};
} else if (this.moduleForm.moduleType === 'repository') {
} else if (this.moduleForm.moduleType === "repository") {
this.moduleRule = {
name: [
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
{max: 60, message: this.$t('test_track.length_less_than') + '60', trigger: 'blur'}
{
required: true,
message: this.$t("test_track.case.input_name"),
trigger: "blur",
},
{
max: 60,
message: this.$t("test_track.length_less_than") + "60",
trigger: "blur",
},
],
repositoryPath: [
{
required: true,
message: this.$t('project.project_file.validation.input_repository_path'),
trigger: 'blur'
message: this.$t(
"project.project_file.validation.input_repository_path"
),
trigger: "blur",
},
{max: 255, message: this.$t('test_track.length_less_than') + '255', trigger: 'blur'},
{
pattern: '(.*)\.git$',
message: this.$t('project.project_file.validation.input_repository_path'),
trigger: 'blur'
}
max: 255,
message: this.$t("test_track.length_less_than") + "255",
trigger: "blur",
},
{
pattern: "(.*)\.git$",
message: this.$t(
"project.project_file.validation.input_repository_path"
),
trigger: "blur",
},
],
repositoryToken: [
{
required: true,
message: this.$t('project.project_file.validation.input_repository_token'),
trigger: 'blur'
message: this.$t(
"project.project_file.validation.input_repository_token"
),
trigger: "blur",
},
{
max: 255,
message: this.$t("test_track.length_less_than") + "255",
trigger: "blur",
},
{max: 255, message: this.$t('test_track.length_less_than') + '255', trigger: 'blur'}
],
};
}
}
},
},
props: {},
computed: {},
@ -153,42 +240,48 @@ export default {
testConnect() {
let param = this.moduleForm;
this.isConnBtnLoading = true;
testConnectRepository(param).then(() => {
this.$success(this.$t('commons.connection_successful'));
this.isConnBtnLoading = false;
}).catch(() => {
this.$emit('refresh');
this.isConnBtnLoading = false;
});
testConnectRepository(param)
.then(() => {
this.$success(this.$t("commons.connection_successful"));
this.isConnBtnLoading = false;
})
.catch(() => {
this.$emit("refresh");
this.isConnBtnLoading = false;
});
},
saveFileModule() {
this.$refs.form.validate(valid => {
this.$refs.form.validate((valid) => {
if (valid) {
let param = this.moduleForm;
param.projectId = this.projectId;
if (this.operationType === 'create') {
if (this.operationType === "create") {
this.isSaveBtnLoading = true;
createFileModule(param).then(() => {
this.$success(this.$t('commons.save_success'));
this.$emit('refresh');
this.isSaveBtnLoading = false;
this.close();
}).catch(() => {
this.isSaveBtnLoading = false;
this.$emit('refresh');
});
} else if (this.operationType === 'edit') {
createFileModule(param)
.then(() => {
this.$success(this.$t("commons.save_success"));
this.$emit("refresh");
this.isSaveBtnLoading = false;
this.close();
})
.catch(() => {
this.isSaveBtnLoading = false;
this.$emit("refresh");
});
} else if (this.operationType === "edit") {
this.isSaveBtnLoading = true;
modifyFileModule(param).then(() => {
this.$success(this.$t('commons.save_success'));
this.$emit('refresh');
this.isSaveBtnLoading = false;
this.close();
}).catch(() => {
this.isSaveBtnLoading = false;
this.$emit('refresh');
});
modifyFileModule(param)
.then(() => {
this.$success(this.$t("commons.save_success"));
this.$emit("refresh");
this.isSaveBtnLoading = false;
this.close();
})
.catch(() => {
this.isSaveBtnLoading = false;
this.$emit("refresh");
});
}
} else {
return false;
@ -200,8 +293,8 @@ export default {
this.isConnBtnLoading = false;
listenGoBack(this.close);
this.initDialog(operationType);
if (operationType === 'create') {
param.moduleType = 'module';
if (operationType === "create") {
param.moduleType = "module";
}
this.moduleForm = JSON.parse(JSON.stringify(param));
this.dialogFormVisible = true;
@ -216,28 +309,26 @@ export default {
initDialog(operationType) {
this.operationType = operationType;
//-title
if (operationType === 'create') {
this.dialogTitle = this.$t('commons.create');
} else if (operationType === 'edit') {
this.dialogTitle = this.$t('commons.edit');
if (operationType === "create") {
this.dialogTitle = this.$t("commons.create");
} else if (operationType === "edit") {
this.dialogTitle = this.$t("commons.edit");
} else {
this.dialogTitle = '';
this.dialogTitle = "";
}
},
clearForm() {
this.moduleForm = {
name: '',
moduleType: 'module',
repositoryPath: '',
repositoryToken: '',
repositoryUserName: '',
repositoryDesc: '',
name: "",
moduleType: "module",
repositoryPath: "",
repositoryToken: "",
repositoryUserName: "",
repositoryDesc: "",
};
}
}
}
},
},
};
</script>
<style scoped>
</style>
<style scoped></style>

View File

@ -363,7 +363,6 @@ export default {
},
beforeUploadFile(file) {
if (!this.fileValidator(file)) {
/// todo:
return false;
}
if (file.size / 1024 / 1024 > 500) {

View File

@ -11,8 +11,8 @@
:update-permission="['PROJECT_API_SCENARIO:READ+EDIT']"
:default-label="$t('commons.module_title')"
:show-case-num="showCaseNum"
:operation_type_add="treeOperationType"
:operation_type_edit="treeOperationType"
operation_type_add="external"
operation_type_edit="external"
@add="add"
@edit="edit"
@drag="drag"
@ -22,24 +22,31 @@
@nodeSelectEvent="nodeChange"
@addOperation="fileTreeModuleAdd"
@editOperation="fileTreeModuleEdit"
ref="nodeTree">
ref="nodeTree"
>
<template v-slot:header>
<ms-search-bar
:show-operator="showOperator"
:condition="condition"/>
<ms-my-file :condition="condition" :exe="myFile" :total='total' v-if="loading"/>
<ms-search-bar :show-operator="showOperator" :condition="condition" />
<ms-my-file
:condition="condition"
:exe="myFile"
:total="total"
v-if="loading"
/>
</template>
</ms-node-tree>
<file-module-dialog @refresh="list" ref="fileModuleDialog"/>
<file-module-dialog @refresh="list" ref="fileModuleDialog" />
</div>
</template>
<script>
import MsNodeTree from "./NodeTree.vue";
import {buildTree} from "metersphere-frontend/src/model/NodeTree";
import { buildTree } from "metersphere-frontend/src/model/NodeTree";
import MsMyFile from "./MyFile";
import MsSearchBar from "metersphere-frontend/src/components/search/MsSearchBar";
import {getCurrentProjectID, getCurrentUserId} from "metersphere-frontend/src/utils/token";
import {
getCurrentProjectID,
getCurrentUserId,
} from "metersphere-frontend/src/utils/token";
import FileModuleDialog from "@/business/menu/file/dialog/FileModuleDialog";
import {
createFileModule,
@ -48,12 +55,11 @@ import {
getFileMeta,
getFileModule,
modifyFileModule,
posModule
posModule,
} from "../../../../api/file";
import {hasLicense} from "metersphere-frontend/src/utils/permission";
export default {
name: 'MsFileModule',
name: "MsFileModule",
components: {
MsSearchBar,
MsMyFile,
@ -65,7 +71,7 @@ export default {
type: Boolean,
default() {
return false;
}
},
},
showOperator: Boolean,
relevanceProjectId: String,
@ -75,17 +81,13 @@ export default {
type: Boolean,
default() {
return true;
}
}
},
},
},
computed: {
projectId() {
return getCurrentProjectID();
},
treeOperationType() {
let returnStr = hasLicense() ? 'external' : 'simple'
return returnStr;
}
},
data() {
return {
@ -95,109 +97,125 @@ export default {
loading: true,
condition: {
filterText: "",
trashEnable: false
trashEnable: false,
},
data: [],
currentModule: undefined,
}
};
},
mounted() {
this.myFiles();
this.list();
},
watch: {
'condition.filterText'() {
"condition.filterText"() {
this.filter();
},
relevanceProjectId() {
this.myFiles();
this.list();
}
},
},
methods: {
fileTreeModuleAdd(param) {
this.$refs.fileModuleDialog.open('create', param);
this.$refs.fileModuleDialog.open("create", param);
},
fileTreeModuleEdit(data) {
this.$refs.fileModuleDialog.open('edit', data);
this.$refs.fileModuleDialog.open("edit", data);
},
reload() {
this.loading = false
this.loading = false;
this.$nextTick(() => {
this.loading = true
this.loading = true;
});
},
filter() {
this.$refs.nodeTree.filter(this.condition.filterText);
},
myFiles() {
this.nodeLoading = getFileMeta(getCurrentProjectID(), getCurrentUserId()).then(res => {
this.nodeLoading = getFileMeta(
getCurrentProjectID(),
getCurrentUserId()
).then((res) => {
this.total = res.data;
});
},
list(projectId) {
this.nodeLoading = getFileModule(projectId ? projectId : this.projectId).then(res => {
this.nodeLoading = getFileModule(
projectId ? projectId : this.projectId
).then((res) => {
if (res.data) {
this.data = res.data;
this.data.forEach(node => {
node.name = node.name === 'DEF_MODULE' ? this.$t('commons.module_title') : node.name
buildTree(node, {path: ''});
this.data.forEach((node) => {
node.name =
node.name === "DEF_MODULE"
? this.$t("commons.module_title")
: node.name;
buildTree(node, { path: "" });
});
this.$emit('setModuleOptions', this.data);
this.$emit('setNodeTree', this.data);
this.$emit("setModuleOptions", this.data);
this.$emit("setNodeTree", this.data);
if (this.$refs.nodeTree) {
this.$refs.nodeTree.filter(this.condition.filterText);
}
}
})
});
},
edit(param) {
param.projectId = this.projectId;
param.protocol = this.condition.protocol;
modifyFileModule(param).then(() => {
this.$success(this.$t('commons.save_success'));
this.list();
this.refresh();
}).catch(() => {
this.list();
});
modifyFileModule(param)
.then(() => {
this.$success(this.$t("commons.save_success"));
this.list();
this.refresh();
})
.catch(() => {
this.list();
});
},
add(param) {
param.projectId = this.projectId;
param.protocol = this.condition.protocol;
createFileModule(param).then(() => {
this.$success(this.$t('commons.save_success'));
this.list();
}).catch(() => {
this.list();
});
},
remove(nodeIds) {
deleteFileModule(nodeIds).then(() => {
this.list();
this.refresh();
}).catch(() => {
this.list();
});
},
drag(param, list) {
dragModule(param).then(() => {
posModule(list).then(() => {
createFileModule(param)
.then(() => {
this.$success(this.$t("commons.save_success"));
this.list();
})
}).catch(() => {
this.list();
});
.catch(() => {
this.list();
});
},
remove(nodeIds) {
deleteFileModule(nodeIds)
.then(() => {
this.list();
this.refresh();
})
.catch(() => {
this.list();
});
},
drag(param, list) {
dragModule(param)
.then(() => {
posModule(list).then(() => {
this.list();
});
})
.catch(() => {
this.list();
});
},
nodeChange(node, nodeIds, pNodes) {
this.currentModule = node.data;
if (!this.condition.filters) {
this.condition.filters = {createUser: []};
this.condition.filters = { createUser: [] };
} else {
this.condition.filters.createUser = [];
}
this.reload();
if (node.data.id === 'root') {
if (node.data.id === "root") {
this.$emit("nodeSelectEvent", node, [], pNodes);
} else {
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
@ -215,16 +233,16 @@ export default {
}
});
if (!this.condition.filters) {
this.condition.filters = {createUser: [getCurrentUserId()]};
this.condition.filters = { createUser: [getCurrentUserId()] };
} else {
this.condition.filters.createUser = [getCurrentUserId()];
}
this.condition.filters.moduleIds = [];
this.$emit("myFile");
this.reload();
}
}
}
},
},
};
</script>
<style scoped>