312 lines
6.9 KiB
Vue
312 lines
6.9 KiB
Vue
<template>
|
||
<Dialog v-if="show" :options="{ title, position: 'top' }" v-model="show">
|
||
<template v-slot:body-content>
|
||
<div class="flex flex-col gap-4">
|
||
<p class="text-base text-gray-600">
|
||
您可以通过输入补丁URL或选择补丁文件来选择应用程序补丁。
|
||
</p>
|
||
<div class="flex flex-col gap-2">
|
||
<FormControl
|
||
v-if="!app"
|
||
class="w-full"
|
||
v-model="applyToApp"
|
||
label="选择应用"
|
||
placeholder="选择要打补丁的应用"
|
||
type="select"
|
||
variant="outline"
|
||
:options="$resources.apps.data"
|
||
/>
|
||
|
||
<!-- 补丁选择器(URL或文件) -->
|
||
<div class="flex w-full items-end gap-1">
|
||
<FormControl
|
||
v-if="!patch"
|
||
class="w-full"
|
||
label="补丁URL"
|
||
type="data"
|
||
v-model="patchURL"
|
||
variant="outline"
|
||
placeholder="输入补丁URL"
|
||
/>
|
||
<FormControl
|
||
v-else
|
||
class="w-full"
|
||
label="补丁文件名"
|
||
type="data"
|
||
variant="outline"
|
||
v-model="patchFileName"
|
||
placeholder="设置补丁文件名"
|
||
/>
|
||
|
||
<!-- 文件选择器 -->
|
||
<input
|
||
ref="fileSelector"
|
||
type="file"
|
||
:accept="['text/x-patch', 'text/x-diff', 'application/x-patch']"
|
||
class="hidden"
|
||
@change="onPatchFileSelect"
|
||
/>
|
||
<Button
|
||
@click="$refs.fileSelector.click()"
|
||
title="选择补丁文件"
|
||
>
|
||
<FeatherIcon name="file-text" class="h-5 w-5 text-gray-600" />
|
||
</Button>
|
||
|
||
<!-- 清除补丁文件 -->
|
||
<Button @click="clear" v-if="patch" title="清除补丁文件">
|
||
<FeatherIcon name="x" class="h-5 w-5 text-gray-600" />
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
<ErrorMessage class="-mt-2 w-full" :message="error" />
|
||
<h3 class="mt-4 text-base font-semibold">补丁配置</h3>
|
||
<FormControl
|
||
v-if="!applyToAllBenches"
|
||
v-model="applyToBench"
|
||
label="选择部署"
|
||
type="select"
|
||
variant="outline"
|
||
:options="$resources.benches.data"
|
||
/>
|
||
<FormControl
|
||
label="将补丁应用到所有活动部署"
|
||
type="checkbox"
|
||
v-model="applyToAllBenches"
|
||
/>
|
||
<FormControl
|
||
label="应用补丁后构建资源"
|
||
type="checkbox"
|
||
v-model="buildAssets"
|
||
/>
|
||
</div>
|
||
</template>
|
||
<template v-slot:actions>
|
||
<Button variant="solid" class="w-full" @click="applyPatch">
|
||
应用补丁
|
||
</Button>
|
||
</template>
|
||
</Dialog>
|
||
</template>
|
||
<script>
|
||
import {
|
||
Button,
|
||
Dialog,
|
||
ErrorMessage,
|
||
FeatherIcon,
|
||
FileUploader,
|
||
FormControl
|
||
} from 'jingrow-ui';
|
||
|
||
export default {
|
||
name: 'PatchAppDialog',
|
||
props: {
|
||
app: [null, String],
|
||
group: String
|
||
},
|
||
components: {
|
||
Dialog,
|
||
FormControl,
|
||
ErrorMessage,
|
||
FileUploader,
|
||
Button,
|
||
FeatherIcon
|
||
},
|
||
watch: {
|
||
app(value) {
|
||
this.show = !!value;
|
||
this.applyToApp = value || '';
|
||
},
|
||
show(value) {
|
||
this.error = '';
|
||
if (value) {
|
||
return;
|
||
}
|
||
|
||
setTimeout(this.clearApp, 150);
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
show: true,
|
||
error: '',
|
||
patch: '',
|
||
patchURL: '',
|
||
patchFileName: '',
|
||
buildAssets: false,
|
||
applyToApp: '',
|
||
applyToBench: '',
|
||
applyToAllBenches: false
|
||
};
|
||
},
|
||
computed: {
|
||
title() {
|
||
const app = this.app || this.applyToApp;
|
||
if (app) {
|
||
return `应用补丁到 ${app}`;
|
||
}
|
||
|
||
return '应用补丁';
|
||
}
|
||
},
|
||
methods: {
|
||
clearApp() {
|
||
this.$emit('clear-app-to-patch');
|
||
},
|
||
validate() {
|
||
if (!this.$resources.benches.data.length) {
|
||
this.error =
|
||
'此部署组没有部署,无法应用补丁。';
|
||
return false;
|
||
}
|
||
if (this.patch && !this.patchFileName) {
|
||
this.error = '请输入补丁文件名。';
|
||
return false;
|
||
}
|
||
|
||
if (!this.patch && !this.patchURL) {
|
||
this.error = '请输入补丁URL或选择一个补丁文件。';
|
||
return false;
|
||
}
|
||
|
||
if (!this.applyToAllBenches && !this.applyToBench) {
|
||
this.error =
|
||
'请选择一个部署或勾选“将补丁应用到所有活动部署”。';
|
||
return false;
|
||
}
|
||
|
||
if (!this.app && !this.applyToApp) {
|
||
this.error = '请选择要打补丁的应用。';
|
||
return false;
|
||
}
|
||
|
||
if (this.patchURL && !this.patchURL.endsWith('.patch')) {
|
||
this.error =
|
||
'补丁URL没有`.patch`扩展名。请输入有效的URL。';
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
},
|
||
applyPatch() {
|
||
if (!this.validate()) {
|
||
return;
|
||
}
|
||
|
||
if (!this.patchFileName && this.patchURL) {
|
||
this.patchFileName = this.patchURL.split('/').at(-1);
|
||
}
|
||
|
||
if (!this.patchFileName.endsWith('.patch')) {
|
||
this.patchFileName += '.patch';
|
||
}
|
||
|
||
const app = this.app || this.applyToApp;
|
||
const args = {
|
||
release_group: this.group,
|
||
app,
|
||
patch_config: {
|
||
patch: this.patch,
|
||
filename: this.patchFileName,
|
||
patch_url: this.patchURL,
|
||
build_assets: this.buildAssets,
|
||
patch_bench: this.applyToBench,
|
||
patch_all_benches: this.applyToAllBenches
|
||
}
|
||
};
|
||
|
||
this.$resources.applyPatch.submit(args);
|
||
},
|
||
async onPatchFileSelect(e) {
|
||
this.error = '';
|
||
const file = e.target.files?.[0];
|
||
if (!file) {
|
||
return;
|
||
}
|
||
|
||
this.patch = await file.text();
|
||
this.patchFileName = file.name;
|
||
},
|
||
clear() {
|
||
this.error = '';
|
||
this.patch = '';
|
||
this.patchFileName = '';
|
||
},
|
||
close() {
|
||
this.show = false;
|
||
this.clear();
|
||
}
|
||
},
|
||
resources: {
|
||
apps() {
|
||
return {
|
||
type: 'list',
|
||
pagetype: 'Release Group App',
|
||
parent: 'Release Group',
|
||
auto: true,
|
||
filters: {
|
||
parenttype: 'Release Group',
|
||
parent: this.group
|
||
},
|
||
onSuccess(data) {
|
||
if (data.length === 1) {
|
||
this.applyToApp = data[0].value;
|
||
}
|
||
},
|
||
onError(data) {
|
||
this.error = data;
|
||
},
|
||
transform(data) {
|
||
return data.map(({ name }) => ({ value: name, label: name }));
|
||
}
|
||
};
|
||
},
|
||
benches() {
|
||
return {
|
||
type: 'list',
|
||
pagetype: 'Bench',
|
||
fields: ['name'],
|
||
filters: {
|
||
group: this.group,
|
||
status: 'Active'
|
||
},
|
||
auto: true,
|
||
onSuccess(data) {
|
||
if (data.length > 0) {
|
||
this.applyToBench = data.at(-1).value;
|
||
return;
|
||
}
|
||
|
||
this.error =
|
||
'此部署组没有部署,无法应用补丁。';
|
||
},
|
||
onError(data) {
|
||
this.error = data;
|
||
},
|
||
transform(data) {
|
||
return data.map(({ name }) => ({ value: name, label: name }));
|
||
}
|
||
};
|
||
},
|
||
applyPatch() {
|
||
return {
|
||
url: 'jcloud.api.bench.apply_patch',
|
||
onSuccess() {
|
||
this.close();
|
||
this.$router.push({
|
||
name: 'Release Group Detail Jobs',
|
||
params: { name: this.group }
|
||
});
|
||
},
|
||
onError(error) {
|
||
if (error.messages.length) {
|
||
this.error = error.messages.join('\n');
|
||
} else {
|
||
this.error = error.message;
|
||
}
|
||
}
|
||
};
|
||
}
|
||
}
|
||
};
|
||
</script> |