fix issue

pull/410/head
vapao 2021-09-04 01:53:58 +08:00
parent 3485d36b85
commit 4e900006be
7 changed files with 137 additions and 18 deletions

View File

@ -8,6 +8,7 @@ from .views import *
urlpatterns = [
path('request/', RequestView.as_view()),
path('request/ext1/', post_request_ext1),
path('request/ext1/rollback/', post_request_ext1_rollback),
path('request/ext2/', post_request_ext2),
path('request/upload/', do_upload),
path('request/<int:r_id>/', RequestDetailView.as_view()),

View File

@ -22,7 +22,7 @@ import os
class RequestView(View):
def get(self, request):
data, query = [], {}
data, query, counter = [], {}, {}
if not request.user.is_supper:
perms = request.user.deploy_perms
query['deploy__app_id__in'] = perms['apps']
@ -48,6 +48,9 @@ class RequestView(View):
tmp['app_host_ids'] = json.loads(item.app_host_ids)
tmp['status_alias'] = item.get_status_display()
tmp['created_by_user'] = item.created_by_user
if item.app_extend == '1':
tmp['visible_rollback'] = item.deploy_id not in counter
counter[item.deploy_id] = True
data.append(tmp)
return json_response(data)
@ -261,6 +264,37 @@ def post_request_ext1(request):
return json_response(error=error)
def post_request_ext1_rollback(request):
form, error = JsonParser(
Argument('request_id', type=int, help='参数错误'),
Argument('name', help='请输入申请标题'),
Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择要部署的主机'),
Argument('desc', required=False),
).parse(request.body)
if error is None:
req = DeployRequest.objects.get(pk=form.pop('request_id'))
requests = DeployRequest.objects.filter(deploy=req.deploy, status__in=('3', '-3'))
versions = list({x.spug_version: 1 for x in requests}.keys())
if req.spug_version not in versions[:req.deploy.extend_obj.versions + 1]:
return json_response(error='选择的版本超出了发布配置中设置的版本数量,无法快速回滚,可通过新建发布申请选择构建仓库里的该版本再次发布。')
form.status = '0' if req.deploy.is_audit else '1'
form.host_ids = json.dumps(sorted(form.host_ids))
new_req = DeployRequest.objects.create(
deploy_id=req.deploy_id,
repository_id=req.repository_id,
type='2',
extra=req.extra,
version=req.version,
spug_version=req.spug_version,
created_by=request.user,
**form
)
if req.deploy.is_audit:
Thread(target=Helper.send_deploy_notify, args=(new_req, 'approve_req')).start()
return json_response(error=error)
def post_request_ext2(request):
form, error = JsonParser(
Argument('id', type=int, required=False),

View File

@ -192,7 +192,7 @@ export default observer(function () {
repositories.map(item => (
<Select.Option key={item.id} value={item.id} disabled={type === '2' && item.id >= rb_id}>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<span>{item.remarks ? `${item.version} (${item.remarks})` : item.version}</span>
<span>{item.version}</span>
<span style={{color: '#999', fontSize: 12}}>构建于 {moment(item.created_at).fromNow()}</span>
</div>
</Select.Option>

View File

@ -0,0 +1,88 @@
/**
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
* Copyright (c) <spug.dev@gmail.com>
* Released under the AGPL-3.0 License.
*/
import React, { useState, useEffect } from 'react';
import { observer } from 'mobx-react';
import { Modal, Form, Input, Select, Button, message } from 'antd';
import HostSelector from './HostSelector';
import hostStore from 'pages/host/store';
import { http, includes } from 'libs';
import store from './store';
import lds from 'lodash';
import moment from 'moment';
export default observer(function () {
const [form] = Form.useForm();
const [visible, setVisible] = useState(false);
const [loading, setLoading] = useState(false);
const [host_ids, setHostIds] = useState([]);
useEffect(() => {
const {app_host_ids, host_ids} = store.record;
setHostIds(lds.clone(host_ids || app_host_ids));
if (!hostStore.records || hostStore.records.length === 0) hostStore.fetchRecords()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
function handleSubmit() {
if (host_ids.length === 0) {
return message.error('请至少选择一个要发布的主机')
}
setLoading(true);
const formData = form.getFieldsValue();
formData['host_ids'] = host_ids;
http.post('/api/deploy/request/ext1/rollback/', formData)
.then(res => {
message.success('操作成功');
store.rollbackVisible = false;
store.fetchRecords()
}, () => setLoading(false))
}
const {app_host_ids, deploy_id} = store.record;
return (
<Modal
visible
width={600}
maskClosable={false}
title="新建回滚发布申请"
onCancel={() => store.rollbackVisible = false}
confirmLoading={loading}
onOk={handleSubmit}>
<Form form={form} initialValues={store.record} labelCol={{span: 5}} wrapperCol={{span: 17}}>
<Form.Item required name="name" label="申请标题">
<Input placeholder="请输入申请标题"/>
</Form.Item>
<Form.Item required name="request_id" label="选择版本">
<Select
showSearch
placeholder="请选择回滚至哪个版本"
filterOption={(input, option) => includes(option.props.children, input)}>
{store.records.filter(x => x.deploy_id === deploy_id && ['3', '-3'].includes(x.status)).map((item, index) => (
<Select.Option key={item.id} value={item.id} record={item} disabled={index === 0}>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<span>{`${item.name} (${item.version})`}</span>
<span style={{color: '#999', fontSize: 12}}>创建于 {moment(item.created_at).fromNow()}</span>
</div>
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item required label="目标主机" tooltip="可以通过创建多个发布申请单,选择主机分批发布。">
{host_ids.length > 0 && `已选择 ${host_ids.length} 台(可选${app_host_ids.length}`}
<Button type="link" onClick={() => setVisible(true)}>选择主机</Button>
</Form.Item>
<Form.Item name="desc" label="备注信息">
<Input placeholder="请输入备注信息"/>
</Form.Item>
</Form>
{visible && <HostSelector
host_ids={host_ids}
app_host_ids={app_host_ids}
onCancel={() => setVisible(false)}
onOk={ids => setHostIds(ids)}/>}
</Modal>
)
})

View File

@ -92,18 +92,16 @@ function ComTable() {
<Popconfirm title="确认要执行该发布申请?" onConfirm={e => handleDeploy(e, info)}>
<Action.Button auth="deploy.request.do">发布</Action.Button>
</Popconfirm>
<Action.Button
auth="deploy.request.do"
disabled={info.type === '2'}
onClick={() => store.rollback(info)}>回滚</Action.Button>
{info.visible_rollback && (
<Action.Button auth="deploy.request.do" onClick={() => store.rollback(info)}>回滚</Action.Button>
)}
</Action>;
case '3':
return <Action>
<Action.Button auth="deploy.request.do" onClick={() => store.readConsole(info)}>查看</Action.Button>
<Action.Button
auth="deploy.request.do"
disabled={info.type === '2'}
onClick={() => store.rollback(info)}>回滚</Action.Button>
{info.visible_rollback && (
<Action.Button auth="deploy.request.do" onClick={() => store.rollback(info)}>回滚</Action.Button>
)}
</Action>;
case '-1':
return <Action>

View File

@ -15,6 +15,7 @@ import ComTable from './Table';
import Ext1Console from './Ext1Console';
import Ext2Console from './Ext2Console';
import BatchDelete from './BatchDelete';
import Rollback from './Rollback';
import { includes } from 'libs';
import envStore from 'pages/config/environment/store';
import appStore from 'pages/config/app/store';
@ -86,6 +87,7 @@ function Index() {
{store.ext2Visible && <Ext2Form/>}
{store.batchVisible && <BatchDelete/>}
{store.approveVisible && <Approve/>}
{store.rollbackVisible && <Rollback/>}
{store.tabs.length > 0 && (
<Space className={styles.miniConsole}>
{store.tabs.map(item => (

View File

@ -21,6 +21,7 @@ class Store {
@observable ext2Visible = false;
@observable batchVisible = false;
@observable approveVisible = false;
@observable rollbackVisible = false;
@observable f_status = 'all';
@observable f_app_id;
@ -96,15 +97,10 @@ class Store {
};
rollback = (info) => {
this.record = lds.pick(info, ['deploy_id', 'app_host_ids', 'host_ids']);
this.record.type = '2';
this.record.rb_id = info.repository_id;
this.record = lds.pick(info, ['deploy_id', 'host_ids']);
this.record.app_host_ids = info.host_ids;
this.record.name = `${info.name} - 回滚`;
if (info.app_extend === '1') {
this.ext1Visible = true
} else {
this.ext2Visible = true
}
this.rollbackVisible = true
}
showForm = (info) => {