mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-11-29 18:38:32 +08:00
feat 节点分发可以指定文件中心发布
This commit is contained in:
parent
b9b14de1d6
commit
7f838e9460
@ -5,6 +5,7 @@
|
||||
### 🐣 新增功能
|
||||
|
||||
1. 【server】新增 节点分发可以指定构建历史产物发布
|
||||
2. 【server】新增 节点分发可以指定文件中心发布
|
||||
|
||||
### 🐞 解决BUG、优化功能
|
||||
|
||||
|
@ -40,6 +40,8 @@ import org.dromara.jpom.common.BaseServerController;
|
||||
import org.dromara.jpom.common.ServerConst;
|
||||
import org.dromara.jpom.common.validator.ValidatorItem;
|
||||
import org.dromara.jpom.common.validator.ValidatorRule;
|
||||
import org.dromara.jpom.func.files.model.FileStorageModel;
|
||||
import org.dromara.jpom.func.files.service.FileStorageService;
|
||||
import org.dromara.jpom.model.AfterOpt;
|
||||
import org.dromara.jpom.model.BaseEnum;
|
||||
import org.dromara.jpom.model.BaseNodeModel;
|
||||
@ -98,6 +100,7 @@ public class OutGivingProjectController extends BaseServerController {
|
||||
private final ProjectInfoCacheService projectInfoCacheService;
|
||||
private final BuildInfoService buildInfoService;
|
||||
private final DbBuildHistoryLogService dbBuildHistoryLogService;
|
||||
private final FileStorageService fileStorageService;
|
||||
|
||||
public OutGivingProjectController(OutGivingServer outGivingServer,
|
||||
OutGivingWhitelistService outGivingWhitelistService,
|
||||
@ -105,7 +108,8 @@ public class OutGivingProjectController extends BaseServerController {
|
||||
DbOutGivingLogService dbOutGivingLogService,
|
||||
ProjectInfoCacheService projectInfoCacheService,
|
||||
BuildInfoService buildInfoService,
|
||||
DbBuildHistoryLogService dbBuildHistoryLogService) {
|
||||
DbBuildHistoryLogService dbBuildHistoryLogService,
|
||||
FileStorageService fileStorageService) {
|
||||
this.outGivingServer = outGivingServer;
|
||||
this.outGivingWhitelistService = outGivingWhitelistService;
|
||||
this.serverConfig = serverConfig;
|
||||
@ -113,6 +117,7 @@ public class OutGivingProjectController extends BaseServerController {
|
||||
this.projectInfoCacheService = projectInfoCacheService;
|
||||
this.buildInfoService = buildInfoService;
|
||||
this.dbBuildHistoryLogService = dbBuildHistoryLogService;
|
||||
this.fileStorageService = fileStorageService;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "getItemData.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ -332,7 +337,6 @@ public class OutGivingProjectController extends BaseServerController {
|
||||
@PostMapping(value = "use-build", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.EXECUTE)
|
||||
public IJsonMessage<String> useBuild(String id, String afterOpt, String clearOld, String buildId, String buildNumberId,
|
||||
String autoUnzip,
|
||||
String secondaryDirectory,
|
||||
String stripComponents,
|
||||
String selectProject,
|
||||
@ -355,7 +359,6 @@ public class OutGivingProjectController extends BaseServerController {
|
||||
EnvironmentMapBuilder environmentMapBuilder = buildHistoryLog.toEnvironmentMapBuilder();
|
||||
boolean tarGz = environmentMapBuilder.getBool(BuildUtil.USE_TAR_GZ, false);
|
||||
int stripComponentsValue = Convert.toInt(stripComponents, 0);
|
||||
boolean unzip = BooleanUtil.toBoolean(autoUnzip);
|
||||
//
|
||||
outGivingModel.setClearOld(Convert.toBool(clearOld, false));
|
||||
outGivingModel.setAfterOpt(afterOpt1.getCode());
|
||||
@ -370,7 +373,7 @@ public class OutGivingProjectController extends BaseServerController {
|
||||
.id(outGivingModel.getId())
|
||||
.file(zipFile)
|
||||
.userModel(getUser())
|
||||
.unzip(unzip)
|
||||
.unzip(unZip)
|
||||
// 由构建配置决定是否删除
|
||||
.doneDeleteFile(false)
|
||||
.mode(outGivingModel.getMode())
|
||||
@ -381,6 +384,56 @@ public class OutGivingProjectController extends BaseServerController {
|
||||
return JsonMessage.success("开始分发!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程文件中心分发文件
|
||||
*
|
||||
* @param id 分发id
|
||||
* @param afterOpt 之后的操作
|
||||
* @return json
|
||||
*/
|
||||
@PostMapping(value = "use-file-storage", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.EXECUTE)
|
||||
public IJsonMessage<String> useFileStorage(String id, String afterOpt, String clearOld, String fileId, String autoUnzip,
|
||||
String secondaryDirectory,
|
||||
String stripComponents,
|
||||
String selectProject,
|
||||
HttpServletRequest request) {
|
||||
|
||||
OutGivingModel outGivingModel = this.check(id, (status, outGivingModel1) -> Assert.state(status != OutGivingModel.Status.ING, "当前还在分发中,请等待分发结束"));
|
||||
AfterOpt afterOpt1 = BaseEnum.getEnum(AfterOpt.class, Convert.toInt(afterOpt, 0));
|
||||
Assert.notNull(afterOpt1, "请选择分发后的操作");
|
||||
FileStorageModel storageModel = fileStorageService.getByKey(fileId, request);
|
||||
Assert.notNull(storageModel, "对应的文件不存在");
|
||||
//
|
||||
outGivingModel.setClearOld(Convert.toBool(clearOld, false));
|
||||
outGivingModel.setAfterOpt(afterOpt1.getCode());
|
||||
outGivingModel.setSecondaryDirectory(secondaryDirectory);
|
||||
outGivingModel.setMode("file-storage");
|
||||
outGivingModel.setModeData(fileId);
|
||||
outGivingServer.updateById(outGivingModel);
|
||||
File storageSavePath = serverConfig.fileStorageSavePath();
|
||||
File file = FileUtil.file(storageSavePath, storageModel.getPath());
|
||||
Assert.state(FileUtil.isFile(file), "当前文件丢失不能执行发布任务");
|
||||
//
|
||||
boolean unzip = BooleanUtil.toBoolean(autoUnzip);
|
||||
//
|
||||
this.checkZip(file, unzip);
|
||||
int stripComponentsValue = Convert.toInt(stripComponents, 0);
|
||||
// 开启
|
||||
OutGivingRun.OutGivingRunBuilder outGivingRunBuilder = OutGivingRun.builder()
|
||||
.id(outGivingModel.getId())
|
||||
.file(file)
|
||||
.userModel(getUser())
|
||||
.unzip(unzip)
|
||||
.mode(outGivingModel.getMode())
|
||||
.modeData(outGivingModel.getModeData())
|
||||
// 可以不再设置-会查询最新的
|
||||
// .projectSecondaryDirectory(secondaryDirectory)
|
||||
.stripComponents(stripComponentsValue);
|
||||
outGivingRunBuilder.build().startRun(selectProject);
|
||||
return JsonMessage.success("开始分发!");
|
||||
}
|
||||
|
||||
@PostMapping(value = "cancel", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.EXECUTE)
|
||||
public IJsonMessage<String> cancel(@ValidatorItem String id) {
|
||||
|
@ -144,6 +144,14 @@ export function useBuild(params) {
|
||||
});
|
||||
}
|
||||
|
||||
export function useuseFileStorage(params) {
|
||||
return axios({
|
||||
url: "/outgiving/use-file-storage",
|
||||
method: "post",
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放分发
|
||||
* @param {*} id 分发 ID
|
||||
|
@ -22,9 +22,10 @@
|
||||
<a-radio :value="'upload'">上传文件</a-radio>
|
||||
<a-radio :value="'download'">远程下载</a-radio>
|
||||
<a-radio :value="'use-build'">构建产物</a-radio>
|
||||
<a-radio :value="'file-storage'">文件中心</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
|
||||
<!-- 手动上传 -->
|
||||
<a-form-model-item label="选择分发文件" prop="clearOld" v-if="temp.type === 'upload'">
|
||||
<a-progress v-if="percentage" :percent="percentage">
|
||||
<template #format="percent">
|
||||
@ -39,18 +40,20 @@
|
||||
<a-button v-else type="primary" icon="upload">选择文件上传</a-button>
|
||||
</a-upload>
|
||||
</a-form-model-item>
|
||||
<!-- 远程下载 -->
|
||||
<a-form-model-item label="远程下载URL" prop="url" v-else-if="temp.type === 'download'">
|
||||
<a-input v-model="temp.url" placeholder="远程下载地址" />
|
||||
</a-form-model-item>
|
||||
<!-- 在线构建 -->
|
||||
<template v-else-if="temp.type == 'use-build'">
|
||||
<a-form-model-item label="选择构建">
|
||||
<a-space>
|
||||
{{ buildInfo.name }}
|
||||
{{ chooseBuildInfo.name }}
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
chooseBuildVisible = 1;
|
||||
chooseVisible = 1;
|
||||
}
|
||||
"
|
||||
>
|
||||
@ -60,13 +63,13 @@
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="选择产物">
|
||||
<a-space>
|
||||
<a-tag v-if="buildInfo.buildNumberId">#{{ buildInfo.buildNumberId }}</a-tag>
|
||||
<a-tag v-if="chooseBuildInfo.buildNumberId">#{{ chooseBuildInfo.buildNumberId }}</a-tag>
|
||||
<a-button
|
||||
type="primary"
|
||||
:disabled="!buildInfo.id"
|
||||
:disabled="!chooseBuildInfo.id"
|
||||
@click="
|
||||
() => {
|
||||
chooseBuildVisible = 2;
|
||||
chooseVisible = 2;
|
||||
}
|
||||
"
|
||||
>
|
||||
@ -75,6 +78,24 @@
|
||||
</a-space>
|
||||
</a-form-model-item>
|
||||
</template>
|
||||
<!-- 文件中心 -->
|
||||
<template v-else-if="temp.type === 'file-storage'">
|
||||
<a-form-model-item label="选择文件">
|
||||
<a-space>
|
||||
{{ chooseFileInfo.name }}
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
chooseVisible = 3;
|
||||
}
|
||||
"
|
||||
>
|
||||
选择文件
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-model-item></template
|
||||
>
|
||||
<a-form-model-item prop="clearOld">
|
||||
<template slot="label">
|
||||
清空发布
|
||||
@ -85,7 +106,7 @@
|
||||
</template>
|
||||
<a-switch v-model="temp.clearOld" checked-children="是" un-checked-children="否" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item prop="unzip">
|
||||
<a-form-model-item prop="unzip" v-if="temp.type !== 'use-build'">
|
||||
<template slot="label">
|
||||
是否解压
|
||||
<a-tooltip>
|
||||
@ -121,32 +142,32 @@
|
||||
destroyOnClose
|
||||
:title="`选择构建`"
|
||||
placement="right"
|
||||
:visible="chooseBuildVisible === 1"
|
||||
:visible="chooseVisible === 1"
|
||||
width="80vw"
|
||||
:zIndex="1009"
|
||||
@close="
|
||||
() => {
|
||||
this.chooseBuildVisible = 0;
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
>
|
||||
<build-list
|
||||
v-if="chooseBuildVisible === 1"
|
||||
v-if="chooseVisible === 1"
|
||||
:choose="'radio'"
|
||||
layout="table"
|
||||
mode="choose"
|
||||
@confirm="
|
||||
(data) => {
|
||||
this.buildInfo = {
|
||||
this.chooseBuildInfo = {
|
||||
id: data[0].id,
|
||||
name: data[0].name,
|
||||
};
|
||||
this.chooseBuildVisible = 0;
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
@cancel="
|
||||
() => {
|
||||
this.chooseBuildVisible = 0;
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
></build-list>
|
||||
@ -156,43 +177,78 @@
|
||||
destroyOnClose
|
||||
:title="`选择构建产物`"
|
||||
placement="right"
|
||||
:visible="chooseBuildVisible === 2"
|
||||
:visible="chooseVisible === 2"
|
||||
width="80vw"
|
||||
:zIndex="1009"
|
||||
@close="
|
||||
() => {
|
||||
this.chooseBuildVisible = 0;
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
>
|
||||
<!-- 选择构建产物 -->
|
||||
<build-history
|
||||
v-if="chooseBuildVisible === 2"
|
||||
v-if="chooseVisible === 2"
|
||||
:choose="'radio'"
|
||||
mode="choose"
|
||||
@confirm="
|
||||
(data) => {
|
||||
this.buildInfo = { ...this.buildInfo, buildNumberId: data[0] };
|
||||
this.chooseBuildVisible = 0;
|
||||
this.chooseBuildInfo = { ...this.chooseBuildInfo, buildNumberId: data[0] };
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
@cancel="
|
||||
() => {
|
||||
this.chooseBuildVisible = 0;
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
></build-history>
|
||||
</a-drawer>
|
||||
<!-- 选择文件 -->
|
||||
<a-drawer
|
||||
destroyOnClose
|
||||
:title="`选择文件`"
|
||||
placement="right"
|
||||
:visible="chooseVisible === 3"
|
||||
width="80vw"
|
||||
:zIndex="1009"
|
||||
@close="
|
||||
() => {
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
>
|
||||
<!-- 选择文件 -->
|
||||
<file-storage
|
||||
v-if="chooseVisible === 3"
|
||||
:choose="'radio'"
|
||||
mode="choose"
|
||||
@confirm="
|
||||
(data) => {
|
||||
this.chooseFileInfo = { id: data[0].id, name: data[0].name };
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
@cancel="
|
||||
() => {
|
||||
this.chooseVisible = 0;
|
||||
}
|
||||
"
|
||||
></file-storage>
|
||||
</a-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { uploadPieces } from "@/utils/upload-pieces";
|
||||
import { remoteDownload, uploadDispatchFile, uploadDispatchFileMerge, afterOptList, getDispatchProject, useBuild } from "@/api/dispatch";
|
||||
import { remoteDownload, uploadDispatchFile, uploadDispatchFileMerge, afterOptList, getDispatchProject, useBuild, useuseFileStorage } from "@/api/dispatch";
|
||||
import { renderSize, formatDuration } from "@/utils/const";
|
||||
import BuildList from "@/pages/build/list-info";
|
||||
import BuildHistory from "@/pages/build/history";
|
||||
import FileStorage from "@/pages/file-manager/fileStorage/list";
|
||||
import { getBuildGet } from "@/api/build-info";
|
||||
import { hasFile } from "@/api/file-manager/file-storage";
|
||||
export default {
|
||||
components: { BuildList, BuildHistory },
|
||||
components: { BuildList, BuildHistory, FileStorage },
|
||||
props: {
|
||||
data: Object,
|
||||
},
|
||||
@ -209,8 +265,9 @@ export default {
|
||||
url: [{ required: true, message: "请输入远程地址", trigger: "blur" }],
|
||||
},
|
||||
temp: { type: "upload" },
|
||||
chooseBuildVisible: 0,
|
||||
buildInfo: {},
|
||||
chooseVisible: 0,
|
||||
chooseBuildInfo: {},
|
||||
chooseFileInfo: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
@ -226,18 +283,29 @@ export default {
|
||||
}
|
||||
});
|
||||
if (this.data.mode === "use-build") {
|
||||
// 构建
|
||||
const buildData = (this.data.modeData || "").split(":");
|
||||
if (buildData.length === 2) {
|
||||
getBuildGet({
|
||||
id: buildData[0],
|
||||
}).then((res) => {
|
||||
if (res.code === 200 && res.data) {
|
||||
this.buildInfo = { id: res.data.id, name: res.data.name, buildNumberId: buildData[1] };
|
||||
this.chooseBuildInfo = { id: res.data.id, name: res.data.name, buildNumberId: buildData[1] };
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (this.data.mode === "download") {
|
||||
// 下载
|
||||
this.temp = { ...this.temp, url: this.data.modeData };
|
||||
} else if (this.data.mode === "file-storage") {
|
||||
// 文件中心
|
||||
if (this.data.modeData) {
|
||||
hasFile({ fileSumMd5: this.data.modeData }).then((res) => {
|
||||
if (res.code === 200 && res.data) {
|
||||
this.chooseFileInfo = { id: res.data.id, name: res.data.name };
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// console.log(this.temp);
|
||||
},
|
||||
@ -357,13 +425,32 @@ export default {
|
||||
});
|
||||
return true;
|
||||
} else if (this.temp.type == "use-build") {
|
||||
if (!this.buildInfo || !this.buildInfo.id || !this.buildInfo.buildNumberId) {
|
||||
// 构建
|
||||
if (!this.chooseBuildInfo || !this.chooseBuildInfo.id || !this.chooseBuildInfo.buildNumberId) {
|
||||
this.$notification.error({
|
||||
message: "请填写构建和产物",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
useBuild({ ...this.temp, buildId: this.buildInfo.id, buildNumberId: this.buildInfo.buildNumberId }).then((res) => {
|
||||
useBuild({ ...this.temp, buildId: this.chooseBuildInfo.id, buildNumberId: this.chooseBuildInfo.buildNumberId }).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
});
|
||||
|
||||
this.$emit("cancel");
|
||||
}
|
||||
});
|
||||
return true;
|
||||
} else if (this.temp.type == "file-storage") {
|
||||
// 文件中心
|
||||
if (!this.chooseFileInfo || !this.chooseFileInfo.id) {
|
||||
this.$notification.error({
|
||||
message: "请填写文件中心文件",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
useuseFileStorage({ ...this.temp, fileId: this.chooseFileInfo.id }).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
|
@ -291,6 +291,35 @@
|
||||
<releaseFile ref="releaseFile" v-if="releaseFileVisible" @commit="handleCommitTask"></releaseFile>
|
||||
</a-modal>
|
||||
</div>
|
||||
<!-- 选择确认区域 -->
|
||||
<div style="padding-top: 50px" v-if="this.choose">
|
||||
<div
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
borderTop: '1px solid #e9e9e9',
|
||||
padding: '10px 16px',
|
||||
background: '#fff',
|
||||
textAlign: 'right',
|
||||
zIndex: 1,
|
||||
}"
|
||||
>
|
||||
<a-space>
|
||||
<a-button
|
||||
@click="
|
||||
() => {
|
||||
this.$emit('cancel');
|
||||
}
|
||||
"
|
||||
>
|
||||
取消
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handerConfirm"> 确定 </a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -306,6 +335,13 @@ export default {
|
||||
components: {
|
||||
releaseFile,
|
||||
},
|
||||
props: {
|
||||
choose: {
|
||||
// "radio"
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
@ -381,6 +417,7 @@ export default {
|
||||
this.tableSelections = selectedRowKeys;
|
||||
},
|
||||
selectedRowKeys: this.tableSelections,
|
||||
type: this.choose || "checkbox",
|
||||
};
|
||||
},
|
||||
},
|
||||
@ -664,6 +701,25 @@ export default {
|
||||
releaseFileOk() {
|
||||
this.$refs.releaseFile?.tryCommit();
|
||||
},
|
||||
// 选择确认
|
||||
handerConfirm() {
|
||||
if (!this.tableSelections.length) {
|
||||
this.$notification.warning({
|
||||
message: "请选择要使用的文件",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const selectData = this.list.filter((item) => {
|
||||
return this.tableSelections.indexOf(item.id) > -1;
|
||||
});
|
||||
if (!selectData.length) {
|
||||
this.$notification.warning({
|
||||
message: "请选择要使用的文件",
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.$emit("confirm", selectData);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user