forked from Gitlink/forgeplus-react
softbot联调
This commit is contained in:
parent
f7033a33e4
commit
d15e2d1c84
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1653550272457') format('woff2'),
|
||||
url('iconfont.woff?t=1653550272457') format('woff'),
|
||||
url('iconfont.ttf?t=1653550272457') format('truetype');
|
||||
src: url('iconfont.woff2?t=1673243764843') format('woff2'),
|
||||
url('iconfont.woff?t=1673243764843') format('woff'),
|
||||
url('iconfont.ttf?t=1673243764843') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,42 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-yuyue-lishi-shijian:before {
|
||||
content: "\e93f";
|
||||
}
|
||||
|
||||
.icon-a-duobianxing1:before {
|
||||
content: "\e93c";
|
||||
}
|
||||
|
||||
.icon-a-duobianxing2:before {
|
||||
content: "\e93d";
|
||||
}
|
||||
|
||||
.icon-sousuo5:before {
|
||||
content: "\e93e";
|
||||
}
|
||||
|
||||
.icon-baogaoppt:before {
|
||||
content: "\e93b";
|
||||
}
|
||||
|
||||
.icon-gailan2:before {
|
||||
content: "\e93a";
|
||||
}
|
||||
|
||||
.icon-bianji7:before {
|
||||
content: "\e939";
|
||||
}
|
||||
|
||||
.icon-ROBOT:before {
|
||||
content: "\e937";
|
||||
}
|
||||
|
||||
.icon-a-zu1404:before {
|
||||
content: "\e938";
|
||||
}
|
||||
|
||||
.icon-tuichuicon:before {
|
||||
content: "\e936";
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,69 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "6978097",
|
||||
"name": "预约-历史-时间",
|
||||
"font_class": "yuyue-lishi-shijian",
|
||||
"unicode": "e93f",
|
||||
"unicode_decimal": 59711
|
||||
},
|
||||
{
|
||||
"icon_id": "31659662",
|
||||
"name": "多边形 1",
|
||||
"font_class": "a-duobianxing1",
|
||||
"unicode": "e93c",
|
||||
"unicode_decimal": 59708
|
||||
},
|
||||
{
|
||||
"icon_id": "31659664",
|
||||
"name": "多边形 2",
|
||||
"font_class": "a-duobianxing2",
|
||||
"unicode": "e93d",
|
||||
"unicode_decimal": 59709
|
||||
},
|
||||
{
|
||||
"icon_id": "31659665",
|
||||
"name": "搜索",
|
||||
"font_class": "sousuo5",
|
||||
"unicode": "e93e",
|
||||
"unicode_decimal": 59710
|
||||
},
|
||||
{
|
||||
"icon_id": "31424249",
|
||||
"name": "报告ppt",
|
||||
"font_class": "baogaoppt",
|
||||
"unicode": "e93b",
|
||||
"unicode_decimal": 59707
|
||||
},
|
||||
{
|
||||
"icon_id": "31318120",
|
||||
"name": "概览",
|
||||
"font_class": "gailan2",
|
||||
"unicode": "e93a",
|
||||
"unicode_decimal": 59706
|
||||
},
|
||||
{
|
||||
"icon_id": "31275425",
|
||||
"name": "编辑",
|
||||
"font_class": "bianji7",
|
||||
"unicode": "e939",
|
||||
"unicode_decimal": 59705
|
||||
},
|
||||
{
|
||||
"icon_id": "30382389",
|
||||
"name": "ROBOT",
|
||||
"font_class": "ROBOT",
|
||||
"unicode": "e937",
|
||||
"unicode_decimal": 59703
|
||||
},
|
||||
{
|
||||
"icon_id": "30382697",
|
||||
"name": "组 1404",
|
||||
"font_class": "a-zu1404",
|
||||
"unicode": "e938",
|
||||
"unicode_decimal": 59704
|
||||
},
|
||||
{
|
||||
"icon_id": "29934961",
|
||||
"name": "退出icon",
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -12,7 +12,7 @@
|
|||
<meta property="og:site_name" content="GitLink" />
|
||||
<meta property="og:description" content="GitLink,新一代开源创新服务平台 分布式协作开发 一站式过程管理 高效流水线运维 多层次代码分析 多维度用户画像 分布式协作开发 基于Git打造分布式代码托管环境" />
|
||||
<meta name="theme-color" content="#000000">
|
||||
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
|
||||
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" /> -->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link href="https://gw.alipayobjects.com/os/lib/alipay/alex/2.0.19/bundle/alex.all.global.min.css" rel="stylesheet"/>
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/iconfont.css">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
|
||||
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
|
|
|
@ -1,39 +1,121 @@
|
|||
import { Button, Checkbox, Radio, Select } from "antd";
|
||||
import React from "react";
|
||||
import { Button, Checkbox, message, Radio, Select, Switch } from "antd";
|
||||
import axios from "axios";
|
||||
import moment from "moment";
|
||||
import React, { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { getInstallBot, updateInstallBot } from "../../../../softbot/api";
|
||||
import { getImageUrl } from 'educoder';
|
||||
import './index.scss';
|
||||
|
||||
function DispositionDetail(props){
|
||||
const {match:{params:{id}}, current_user} = props;
|
||||
const [checkValue, setCheckValue] = useState(0);
|
||||
const [selectValue, setSelectValue] = useState([]);
|
||||
const [options, setOptions] = useState(['仓库1', '仓库2仓库2', '仓库仓库2仓库2仓库2仓库2仓库2', '仓库4', '仓库5']);
|
||||
const filterOption = options.filter(item=>!selectValue.includes(item));
|
||||
const [botDetail, setBotDetail] = useState(undefined);
|
||||
const [options, setOptions] = useState(undefined);
|
||||
const [filterOption, setFilterOption] = useState([]);
|
||||
// bot状态
|
||||
const [botState, setBotState] = useState(true);
|
||||
// const filterOption = options.filter(item=>!selectValue.includes(item));
|
||||
|
||||
// 获取bot详情
|
||||
useEffect(()=>{
|
||||
getInstallBot({
|
||||
user_id: current_user && current_user.user_id,
|
||||
bot_id: id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
const {state} = res.data;
|
||||
setBotState(state);
|
||||
setBotDetail(res.data);
|
||||
}
|
||||
})
|
||||
// 查询用户创建的仓库信息
|
||||
current_user && axios.get(`/users/${current_user.login}/projects.json`,{
|
||||
params:{
|
||||
limit: 1000,
|
||||
page: 1,
|
||||
category:"manage"
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setOptions(result.data.projects);
|
||||
setFilterOption(result.data.projects);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}, [])
|
||||
|
||||
// 监听已选项selectValue的变化 改变下拉选择框的选择项
|
||||
useEffect(()=>{
|
||||
const ids = selectValue.map(item=>{return item.id});
|
||||
options && setFilterOption(options.filter(item=>!ids.includes(item.id)));
|
||||
}, [selectValue])
|
||||
|
||||
// 比较全部仓库和安装的仓库数组
|
||||
useEffect(()=>{
|
||||
if(botDetail && options){
|
||||
if(botDetail.store_id_list.length === options.length){
|
||||
setCheckValue(0);
|
||||
}else{
|
||||
setCheckValue(1);
|
||||
// 把已选择仓库筛选出来
|
||||
const {store_id_list} = botDetail;
|
||||
const allStoreId = options.map((item)=>{return item.id});
|
||||
let newMap = selectValue;
|
||||
store_id_list.map(item=>{
|
||||
if(allStoreId.includes(item)){
|
||||
newMap = newMap.concat(options.filter(i=>{return i.id === item})[0]);
|
||||
}
|
||||
})
|
||||
setSelectValue(newMap);
|
||||
}
|
||||
}
|
||||
|
||||
}, [options, botDetail])
|
||||
|
||||
function selectChange(e){
|
||||
let newMap = selectValue;
|
||||
newMap = newMap.concat(e);
|
||||
newMap = newMap.concat(options.filter(i=>{return i.id === e})[0]);
|
||||
setSelectValue(newMap);
|
||||
}
|
||||
|
||||
function deleteSelect(e){
|
||||
let newMap = selectValue;
|
||||
newMap = newMap.filter(item=>{return item !== e});
|
||||
newMap = newMap.filter(item=>{return item.id !== e.id});
|
||||
setSelectValue(newMap);
|
||||
}
|
||||
|
||||
function updateInsBot(){
|
||||
updateInstallBot({
|
||||
bot_id: id,
|
||||
password: "",
|
||||
state: botState ? 1 : 0,
|
||||
store_list: checkValue ? selectValue.map(item=>{return item.id}) : options.map(item=>{return item.id}),
|
||||
user_id: current_user && current_user.user_id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success('更改成功');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return <div className="dispositionDetailBox">
|
||||
<div className="oneLine mb30">
|
||||
<div className="oneLine">
|
||||
<img src="" alt="" className="botImg imgBox"/>
|
||||
{botDetail && <img src={getImageUrl(botDetail.logo)} alt="" className="botImg imgBox"/>}
|
||||
<div className="ml40 font-16">
|
||||
<div className="font-22">Bot名称</div>
|
||||
<span className="mr30 color88">开发者姓名</span>
|
||||
<span className="color88">2022-6-23</span>
|
||||
<div className="font-22">{botDetail && botDetail.market_name}</div>
|
||||
<span className="mr30 color88">{botDetail && botDetail.register_id}</span>
|
||||
<span className="color88">{botDetail && botDetail.market_time && moment(botDetail.market_time).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<Button style={{width: '53px', padding: '0'}} className="grayBorBut"><Link to={`/settings/dispositionBot`}>返回</Link></Button>
|
||||
</div>
|
||||
<div className="mb10"><Checkbox className="greenCol font-16">代码库只读权限</Checkbox></div>
|
||||
<div className="mb20"><Checkbox className="greenCol font-16">合并请求(PR)读写权限</Checkbox></div>
|
||||
{botDetail && <div className="mb10"><Checkbox className="greenCol font-16" checked={botDetail.limit_vo.juris_diction_code !== 2}>代码库{botDetail.limit_vo.juris_diction_code === 2 ? '无' : botDetail.limit_vo.juris_diction_code === 1 ? '读写' : '只读'}权限</Checkbox></div>}
|
||||
{botDetail && <div className="mb20"><Checkbox className="greenCol font-16" checked={botDetail.limit_vo.juris_diction_pr !== 2}>合并请求(PR){botDetail.limit_vo.juris_diction_pr === 2 ? '无' : botDetail.limit_vo.juris_diction_pr === 1 ? '读写' : '只读'}权限</Checkbox></div>}
|
||||
<div className="detailTil font-16">更改安装位置</div>
|
||||
<div>
|
||||
<Radio.Group onChange={(e)=>{setCheckValue(e.target.value)}} value={checkValue}>
|
||||
|
@ -41,38 +123,45 @@ function DispositionDetail(props){
|
|||
<Radio value={1} className="radioBox mt15 font-16">安装到指定仓库<br/><span className="font-15 radioBoxTip">请至少选择一个仓库</span></Radio>
|
||||
</Radio.Group>
|
||||
{checkValue === 1 && <Select
|
||||
placeholder="请输入仓库名称"
|
||||
value={selectValue}
|
||||
placeholder="请选择仓库名称"
|
||||
value={selectValue.map(item=>{return item.id})}
|
||||
onChange={selectChange}
|
||||
className="radioBox selectBox"
|
||||
>
|
||||
{filterOption.map(item=>(<Select.Option key={item} value={item}>{item}</Select.Option>))}
|
||||
{filterOption.map(item=>(<Select.Option key={item.id} value={item.id}>{item.name}</Select.Option>))}
|
||||
</Select>}
|
||||
{selectValue.map((item, index)=>{return <div key={index} className="selectValueBox font-14"><i className="iconfont icon-daimakuicon1 font-14 mr5"></i><span className="selectValue">{item}</span><i className="iconfont icon-guanbi font-12 close ml30" onClick={()=>{deleteSelect(item)}}></i></div>})}
|
||||
{checkValue === 1 && selectValue.map((item, index)=>{return <div key={index} className="selectValueBox font-14"><i className="iconfont icon-daimakuicon1 font-14 mr5"></i><span className="selectValue">{item.name}</span><i className="iconfont icon-guanbi font-12 close ml30" onClick={()=>{deleteSelect(item)}}></i></div>})}
|
||||
</div>
|
||||
<div className="detailTil font-16 mt30">更改Bot状态</div>
|
||||
<div className="disBotItem">
|
||||
<div className="detailTil font-16 mt30 mb10">更改Bot状态</div>
|
||||
{/* {botDetail && botDetail.state === 1 && <div className="disBotItem">
|
||||
<div>
|
||||
<div className="font-15">挂起</div>
|
||||
<span className='changeStatusTip'>暂停停止使用该bot,阻塞该bot拥有的仓库访问权限</span>
|
||||
</div>
|
||||
<Button className="dangerBorBut" style={{width: '88px', height: '36px'}}>挂起</Button>
|
||||
</div>
|
||||
<div className="disBotItem">
|
||||
</div>}
|
||||
{botDetail && botDetail.state === 0 && <div className="disBotItem">
|
||||
<div>
|
||||
<div className="font-15">启用</div>
|
||||
<span className='changeStatusTip'>开始使用该Bot,授予该Bot所需的仓库访问权限</span>
|
||||
</div>
|
||||
<Button className="themeCorBorBut" style={{width: '88px', height: '36px'}}>启用</Button>
|
||||
</div>} */}
|
||||
<div className="ml25">
|
||||
{botDetail && <Switch defaultChecked = {botDetail.state} onChange={(checked)=>{setBotState(checked)}}/>}
|
||||
<div className="mt10">
|
||||
<div className="font-15">{botState ? '启用' : '挂起'}</div>
|
||||
<span className='changeStatusTip'>{botState ? '开始使用该Bot,授予该Bot所需的仓库访问权限' : '暂停停止使用该bot,阻塞该bot拥有的仓库访问权限'}</span>
|
||||
</div>
|
||||
<div className="disBotItem">
|
||||
</div>
|
||||
{/* <div className="disBotItem">
|
||||
<div>
|
||||
<div className="font-15">卸载</div>
|
||||
<span className='changeStatusTip'>将该bot从仓库中卸载,回收所有分配给该bot的权限,将其从安装列表中删除</span>
|
||||
</div>
|
||||
<Button className="dangerBorBut" style={{width: '88px', height: '36px'}}>卸载</Button>
|
||||
</div>
|
||||
<Button type="primary" style={{width: '100px', height: '36px'}} className="mt30">保存</Button>
|
||||
</div> */}
|
||||
<Button type="primary" style={{width: '100px', height: '36px'}} className="mt30" onClick={updateInsBot}>保存</Button>
|
||||
</div>
|
||||
}
|
||||
export default DispositionDetail;
|
|
@ -1,25 +1,80 @@
|
|||
import React, { useState } from "react";
|
||||
import { Button } from "antd";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Button, message, Modal } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import { getImageUrl } from 'educoder';
|
||||
import nullBot from '../../../../softbot/image/notBot.png';
|
||||
import { getAllInstallBots, deleteInstallBot } from "../../../../softbot/api";
|
||||
import './index.scss';
|
||||
|
||||
// 配置已安装的bot
|
||||
function DispositionBot(props){
|
||||
const [botList, setBotList] = useState([{botName: '此处为名称标题内容', status: '0', id: '0'}, {botName: '此处为名称标题内容', status: '1', id: '1'}]);
|
||||
const {current_user} = props;
|
||||
const [botList, setBotList] = useState(undefined);
|
||||
const [delBotId, setDelBotId] = useState(undefined);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [reload, setReload] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
getAllInstallBots({
|
||||
"user_id": current_user && current_user.user_id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setBotList(res.data.install_bots);
|
||||
}
|
||||
})
|
||||
}, [reload])
|
||||
|
||||
function delInstallBot(){
|
||||
deleteInstallBot({
|
||||
user_id: current_user && current_user.user_id,
|
||||
bot_id: delBotId,
|
||||
password: ""
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success('卸载成功');
|
||||
setVisible(false);
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return <div>
|
||||
<div className="dispositionHead font-18">Bot配置</div>
|
||||
{/* bot列表显示区域 */}
|
||||
{botList.length > 0 ? <div className="setBotListBox">
|
||||
{botList && (botList.length > 0 ? <div className="setBotListBox">
|
||||
{botList.map((item, index)=>{return <div className="disBotItem" key={index}>
|
||||
<div>
|
||||
<img src="" alt="" className="imgBox mr20"/>
|
||||
<span className="font-15">{item.botName}</span>
|
||||
<span className={`statusBox font-12 ml10 ${item.status === '0' ? 'active' : ''}`}>{item.status === '0' ? '启用' : '挂起'}</span>
|
||||
<img src={getImageUrl(item.logo)} alt="" className="imgBox mr20"/>
|
||||
<span className="font-15">{item.bot_name}</span>
|
||||
<span className={`statusBox font-12 ml10 ${item.state === '0' ? '' : 'active'}`}>{item.state === '0' ? '挂起' : '启用'}</span>
|
||||
</div>
|
||||
<div>
|
||||
<Button className="themeCorBorBut" style={{width: '68px', height: '36px'}}><Link to={`/settings/dispositionBot/${item.bot_id}`}>配置</Link></Button>
|
||||
<Button className="dangerBorBut ml20" style={{width: '68px', height: '36px'}} onClick={()=>{setDelBotId(item.bot_id);setVisible(true)}}>卸载</Button>
|
||||
</div>
|
||||
<Button className="themeCorBorBut" style={{width: '68px', height: '36px'}}><Link to={`/settings/dispositionBot/${item.id}`}>配置</Link></Button>
|
||||
</div>})}
|
||||
</div> : <div className="font-16 setBotListBox">欢迎使用Bot! Bot可以帮助项目贡献者处理繁杂的项目任务,比如关闭疑修、合并请求。在使用之前,请先注册一个Bot</div>}
|
||||
</div> : <div className="nullBotsBox mt80">
|
||||
<img src={nullBot} alt="" width={62}/>
|
||||
<p className="font-18 showBigTip">您当前暂未安装任何Bot</p>
|
||||
<div className="showTip font-14">Bot可以帮助项目贡献者处理繁杂的项目任务,比如关闭疑修、合并请求等,以节约时间精力提升开发效率。快去市场中挑选一个适合您项目的Bot吧!</div>
|
||||
<div className="borTip"></div>
|
||||
<Button type="primary" style={{width: '112px', height: '36px', padding: 0}}><Link to={'/softbot'}>去Bot市场逛逛</Link></Button>
|
||||
</div>)}
|
||||
<Modal
|
||||
className="f8HeadModal"
|
||||
width="485px"
|
||||
title="卸载Bot"
|
||||
visible={visible}
|
||||
maskClosable={false}
|
||||
footer={[
|
||||
<Button onClick={()=>{setVisible(false)}} className="mr30 grayBorBut whiteBackBut" style={{width:"104px", height: '36px'}}>取消</Button>,
|
||||
<Button className="redFontBut grayBorBut whiteBackBut" style={{width:"104px", height: '36px'}} onClick={delInstallBot}>确认卸载</Button>
|
||||
]}
|
||||
onCancel={()=>{setVisible(false)}}
|
||||
>
|
||||
<div className="font-16 titleTip mt20"><span className="circleRed font-18">!</span>您确定要卸载此Bot吗?</div>
|
||||
<div className="deleteTip">卸载后,将回收所有分配给该bot的权限</div>
|
||||
</Modal>
|
||||
</div>
|
||||
}
|
||||
export default DispositionBot;
|
|
@ -32,7 +32,6 @@
|
|||
.imgBox{
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background-color: yellow;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.dispositionDetailBox{
|
||||
|
@ -102,3 +101,19 @@
|
|||
}
|
||||
.changeStatusTip{color:#99a2af;}
|
||||
}
|
||||
.nullBotsBox{
|
||||
border-radius: 4px 4px 0px 0px;
|
||||
text-align: center;
|
||||
padding: 25px 158px 65px;
|
||||
.showBigTip{
|
||||
color:#333333;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 22px !important;
|
||||
}
|
||||
.showTip{color: #666;}
|
||||
.borTip{
|
||||
width: 82%;
|
||||
margin: 20px auto 18px;
|
||||
border-top: 1px solid rgba(90, 117, 193, 0.23)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
import React ,{useEffect, useRef, useState} from 'react';
|
||||
import { Modal , message } from 'antd';
|
||||
import Cropper from 'react-cropper';
|
||||
import 'cropperjs/dist/cropper.css';
|
||||
import axios from 'axios';
|
||||
import '../../../../../../forge/users/Avatar/Index.scss';
|
||||
|
||||
function Index({onCancel,avatarImg,id, botDetail}){
|
||||
|
||||
const [ avatarPhoto , setAvatarPhoto ] = useState(avatarImg);
|
||||
|
||||
useEffect(()=>{
|
||||
if(avatarImg){
|
||||
setAvatarPhoto(avatarImg);
|
||||
}
|
||||
},[avatarImg])
|
||||
|
||||
const cropper = useRef();
|
||||
|
||||
const saveAvatar = async () => {
|
||||
const imgUrl = cropper.current.cropper.getCroppedCanvas().toDataURL("image/png");
|
||||
if (!imgUrl) {
|
||||
message.info('请先上传图片');
|
||||
}
|
||||
const params = {
|
||||
...botDetail,
|
||||
bot_id: parseInt(id)
|
||||
}
|
||||
console.log('params', params);
|
||||
registerUpdateBot(params).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success("更改成功");
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onChange(e){
|
||||
|
||||
let files;
|
||||
if (e.dataTransfer) {
|
||||
files = e.dataTransfer.files;
|
||||
} else if (e.target) {
|
||||
files = e.target.files;
|
||||
}
|
||||
|
||||
if (!files || (files && files.length===0)) {
|
||||
return;
|
||||
}
|
||||
const file = files[0];
|
||||
if (!/^image\/\w+/.test(file.type)) {
|
||||
message.info('请选择一个图片格式的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.size > 2 * 1024 * 1024) {
|
||||
message.info('仅支持文件大小小于2M的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
if(reader.result){
|
||||
setAvatarPhoto(reader.result);
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(files[0]);
|
||||
}
|
||||
|
||||
return(
|
||||
<Modal
|
||||
visible={true}
|
||||
width="638px"
|
||||
footer={null}
|
||||
centered
|
||||
maskClosable={false}
|
||||
title="修改头像"
|
||||
onCancel={()=>onCancel(false)}
|
||||
className="avatarBox"
|
||||
>
|
||||
<div className="avatarDiv">
|
||||
<div>
|
||||
<Cropper
|
||||
style={{ height: 320, width: 320 }}
|
||||
src={avatarPhoto}
|
||||
guides={false}
|
||||
preview="#updateAvatarImg"
|
||||
ref={cropper}
|
||||
aspectRatio={1}
|
||||
/>
|
||||
{/* <span className={"tips"}>仅支持JPG、GIF、PNG,且文件小于2M</span> */}
|
||||
</div>
|
||||
<div className="previewBox">
|
||||
<div className={"previewImg"} id="updateAvatarImg"></div>
|
||||
<div className="uploadBtn">
|
||||
<label className={"uploadButton"} id="uploadBtn" htmlFor="inputImage">
|
||||
<input type="file" className="sr-only" id="inputImage" name="file" accept="image/*" style={{ display: "none" }} onChange={onChange}></input>
|
||||
点击上传
|
||||
</label>
|
||||
<a onClick={saveAvatar}>保存头像</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default Index;
|
|
@ -1,23 +1,36 @@
|
|||
import { AutoComplete, Button, Modal } from "antd";
|
||||
import { AutoComplete, Button, message, Modal } from "antd";
|
||||
import React from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { getImageUrl } from 'educoder';
|
||||
import './index.scss';
|
||||
import axios from "axios";
|
||||
import { Link } from "react-router-dom";
|
||||
import { deleteBot, transferBot, registerUpdateBot, downMarket, getMarketBotById, cancelTransferBot } from "../../../../../../softbot/api";
|
||||
const { Option } = AutoComplete;
|
||||
|
||||
// 注册一个新的Bot
|
||||
function AdvancedInformation(props){
|
||||
const {match} = props;
|
||||
const {params:{id}} = match;
|
||||
const {match, current_user, match:{params:{id}}, botDetail, setReload} = props;
|
||||
const [ visibleMakeOver, setVisibleMakeOver] = useState(false);
|
||||
const [ newId , setNewId] = useState(undefined);
|
||||
const [ source , setSource ] = useState(undefined);
|
||||
const [ searchKey , setSearchKey ] = useState(undefined);
|
||||
// 删除0、公开1、私有2bot
|
||||
// bot删除0、公开1、私有2
|
||||
const [ type, setType] = useState(undefined);
|
||||
const [ visibleDelete, setVisibleDelete] = useState(false);
|
||||
// 转让bot错误提示
|
||||
const [makeOverErrortTip, setMakeOverErrortTip] = useState(undefined);
|
||||
// 是否已经上架
|
||||
const [isMarket, setIsMarket] = useState(false);
|
||||
// 上下架刷新
|
||||
const [marketReload, setMarketReload] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
// 获取bot是否已经上架
|
||||
getMarketBotById({bot_id: id}).then(res=>{
|
||||
res && setIsMarket(res.code === 200);
|
||||
})
|
||||
}, [marketReload])
|
||||
|
||||
useEffect(()=>{
|
||||
getUserList();
|
||||
|
@ -45,7 +58,7 @@ function AdvancedInformation(props){
|
|||
|
||||
// 选择用户
|
||||
function selectInputUser(e, option){
|
||||
setNewId(option.props.login);
|
||||
setNewId(option.props.value);
|
||||
setSearchKey(option.props.name);
|
||||
};
|
||||
|
||||
|
@ -77,17 +90,90 @@ function AdvancedInformation(props){
|
|||
|
||||
// 确定转让点击函数
|
||||
function makeOver(){
|
||||
console.log('bei', newId);
|
||||
setMakeOverErrortTip(undefined);
|
||||
if(newId){
|
||||
transferBot({
|
||||
"user_id": current_user && current_user.user_id,
|
||||
"user_name": current_user && current_user.username,
|
||||
"bot_id": parseInt(id),
|
||||
"transfer_to_user_id": parseInt(newId)
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success('操作成功');
|
||||
setNewId(undefined);
|
||||
setVisibleMakeOver(false);
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}else{
|
||||
setMakeOverErrortTip("请选择被转让者");
|
||||
}
|
||||
}
|
||||
|
||||
// 删除/公开/私有/下架Bot弹框
|
||||
function submitModal(){
|
||||
if(type === '3'){
|
||||
// 下架市场
|
||||
downMarket(parseInt(id), {}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success('下架成功');
|
||||
setVisibleDelete(false);
|
||||
setMarketReload(Math.random());
|
||||
}
|
||||
})
|
||||
}else if(type === '0'){
|
||||
// 删除bot
|
||||
const params = {
|
||||
user_id: current_user && current_user.user_id,
|
||||
bot_id: parseInt(id)
|
||||
}
|
||||
deleteBot(params).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success('删除成功');
|
||||
setVisibleDelete(false);
|
||||
props.history.push("/settings/exploitBot/configuration");
|
||||
}
|
||||
})
|
||||
}else{
|
||||
// 公开/私有bot
|
||||
const params = {
|
||||
...botDetail,
|
||||
bot_id: parseInt(id),
|
||||
is_public: type === '1' ? 1 : 0
|
||||
}
|
||||
registerUpdateBot(params).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setVisibleDelete(false);
|
||||
message.success("更改成功");
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function cancelTra(){
|
||||
cancelTransferBot({
|
||||
bot_id: parseInt(id),
|
||||
user_id: current_user && current_user.user_id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success("操作成功");
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return <div className="advancedInformationBox">
|
||||
<div className="informationHead pb15">高级选项</div>
|
||||
{/* 提示:转让中状态 */}
|
||||
{botDetail && botDetail.is_transfer_success === 2 && <div className="transferBotStatus mt15"><i className="iconfont icon-yuyue-lishi-shijian font-18 mr5 ml10"></i>此Bot正在等待转移至{botDetail.transfer_to_id}(用户账号)</div>}
|
||||
<div className="disFlex itemBox">
|
||||
<div className="font-15">
|
||||
转让该Bot的所有权至其他用户
|
||||
<p className="grayBox font-14">转让可能会推迟,直到新的所有者批准转让</p>
|
||||
</div>
|
||||
<Button className="themeCorBorBut" style={{width:"88px", height: '36px', padding: '0'}} onClick={()=>{setVisibleMakeOver(true)}}>转让所有权</Button>
|
||||
{botDetail && (botDetail.is_transfer_success !== 2 ? <Button className="themeCorBorBut" style={{width:"88px", height: '36px', padding: '0'}} onClick={()=>{setVisibleMakeOver(true)}}>转让所有权</Button> :
|
||||
<Button className="themeCorBorBut" style={{width:"88px", height: '36px', padding: '0'}} onClick={cancelTra}>取消转让</Button>)}
|
||||
</div>
|
||||
<div className="disFlex itemBox">
|
||||
<div className="font-15">
|
||||
|
@ -96,14 +182,14 @@ function AdvancedInformation(props){
|
|||
</div>
|
||||
<Button className="dangerBorBut" style={{width:"88px", height: '36px', padding: '0'}} onClick={()=>{setType('0');setVisibleDelete(true)}}>删除Bot</Button>
|
||||
</div>
|
||||
<div className="disFlex itemBox">
|
||||
{botDetail && !botDetail.is_public && <div className="disFlex itemBox">
|
||||
<div className="font-15">
|
||||
私有Bot
|
||||
<p className="grayBox font-14">目前您的bot将不能被其他用户安装</p>
|
||||
</div>
|
||||
<Button className="themeCorBorBut" style={{width:"88px", height: '36px', padding: '0'}} onClick={()=>{setType('1');setVisibleDelete(true)}}>公开此Bot</Button>
|
||||
</div>
|
||||
<div className="disFlex itemBox">
|
||||
</div>}
|
||||
{botDetail && !!botDetail.is_public && !isMarket && <div className="disFlex itemBox">
|
||||
<div className="font-15">
|
||||
公开Bot
|
||||
<p className="grayBox font-14">目前您的Bot所有用户都能安装</p>
|
||||
|
@ -112,17 +198,17 @@ function AdvancedInformation(props){
|
|||
<Button type="primary" style={{width:"88px", height: '36px', padding: '0'}} className="mr20"><Link to={`/settings/exploitBot/configuration/${id}/advanced/putaway`}>上架市场</Link></Button>
|
||||
<Button className="themeCorBorBut" style={{width:"88px", height: '36px', padding: '0'}} onClick={()=>{setType('2');setVisibleDelete(true)}}>私有此Bot</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="disFlex itemBox">
|
||||
</div>}
|
||||
{botDetail && !!botDetail.is_public && isMarket && <div className="disFlex itemBox">
|
||||
<div className="font-15">
|
||||
公开Bot
|
||||
<p className="grayBox font-14">目前您的Bot所有用户都能安装</p>
|
||||
</div>
|
||||
<div>
|
||||
<Button type="primary" style={{width:"88px", height: '36px', padding: '0'}} className="mr20">编辑</Button>
|
||||
<Button className="themeCorBorBut" style={{width:"88px", height: '36px', padding: '0'}}>下架市场</Button>
|
||||
</div>
|
||||
<Button type="primary" style={{width:"88px", height: '36px', padding: '0'}} className="mr20"><Link to={`/settings/exploitBot/configuration/${id}/advanced/putaway/edit`}>编辑</Link></Button>
|
||||
<Button className="themeCorBorBut" style={{width:"88px", height: '36px', padding: '0'}} onClick={()=>{setType('3');setVisibleDelete(true)}}>下架市场</Button>
|
||||
</div>
|
||||
</div>}
|
||||
{/* 转让bot弹框 */}
|
||||
<Modal
|
||||
className="themeHeadModal"
|
||||
|
@ -131,8 +217,9 @@ function AdvancedInformation(props){
|
|||
visible={visibleMakeOver}
|
||||
maskClosable={false}
|
||||
footer={null}
|
||||
onCancel={()=>{setVisibleMakeOver(false)}}>
|
||||
onCancel={()=>{setVisibleMakeOver(false);setMakeOverErrortTip(undefined)}}>
|
||||
<div className="font-15 mt5 mb10 makeOverTip">新的所有者账号</div>
|
||||
{makeOverErrortTip && <div className="font-15 mt5 mb10 makeOverErrorTip">{makeOverErrortTip}</div>}
|
||||
<AutoComplete
|
||||
dataSource={source}
|
||||
value={searchKey}
|
||||
|
@ -144,21 +231,21 @@ function AdvancedInformation(props){
|
|||
/>
|
||||
<Button type="primary" onClick={makeOver} className="makeOverSubmit" style={{width:"104px", height: '36px'}}>确认转让</Button>
|
||||
</Modal>
|
||||
{/* 删除Bot弹框 */}
|
||||
{/* 删除/公开/私有Bot弹框 */}
|
||||
<Modal
|
||||
className="f8HeadModal"
|
||||
width="550px"
|
||||
title={`${type === '0' ? '删除' : type === '1' ? '公开' : '私有'}Bot`}
|
||||
title={`${type === '0' ? '删除' : type === '1' ? '公开' : type === '2' ? '私有' : '下架'}Bot`}
|
||||
visible={visibleDelete}
|
||||
maskClosable={false}
|
||||
footer={[
|
||||
<Button onClick={()=>{setVisibleDelete(false)}} className="mr30 grayBorBut whiteBackBut" style={{width:"104px", height: '36px'}}>取消</Button>,
|
||||
<Button className="redFontBut grayBorBut whiteBackBut" style={{width:"104px", height: '36px'}}>确认{type === '0' ? '删除' : type === '1' ? '公开' : '私有'}</Button>
|
||||
<Button className="redFontBut grayBorBut whiteBackBut" style={{width:"104px", height: '36px'}} onClick={submitModal}>确认{type === '0' ? '删除' : type === '1' ? '公开' : type === '2' ? '私有' : '下架'}</Button>
|
||||
]}
|
||||
onCancel={()=>{setVisibleDelete(false)}}
|
||||
>
|
||||
<div className="font-16 titleTip mt20"><span className="circleRed font-18">!</span>您确定要{type === '0' ? '删除此Bot' : type === '1' ? `公开hhhBot` : `私有hhhBot`}吗?</div>
|
||||
<div className="deleteTip">{type === '0' ? '该操作无法撤销,将会永久删除XXXXXBot' : type === '1' ? `公开后,任何用户都可以安装此Bot` : `私有后,此Bot将只能被‘Bot开发者账户’安装`}</div>
|
||||
<div className="font-16 titleTip mt20"><span className="circleRed font-18">!</span>您确定要{type === '0' ? '删除此Bot' : type === '1' ? `公开` : type === '2' ? '私有' : '下架'}{botDetail && botDetail.bot_name}吗?</div>
|
||||
<div className="deleteTip">{type === '0' ? `该操作无法撤销,将会永久删除${botDetail && botDetail.bot_name}` : type === '1' ? `公开后,任何用户都可以安装此Bot` : type === '2' ? '私有后,此Bot将只能被‘Bot开发者账户’安装' : '下架后,社区用户将无法在市场搜索到此Bot'}</div>
|
||||
</Modal>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,43 +1,76 @@
|
|||
import React from "react";
|
||||
import { Button, Form, Input } from "antd";
|
||||
import { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Button, Form, Input, message } from "antd";
|
||||
import MDEditor from '../../../../../../modules/tpm/challengesnew/tpm-md-editor';
|
||||
import { Box } from "../../../../../Component/layout";
|
||||
import miyao from '../../../../img/miyao.png';
|
||||
import './index.scss';
|
||||
import { useEffect } from "react";
|
||||
// 注册一个新的Bot
|
||||
import { Link } from "react-router-dom";
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { registerUpdateBot } from "../../../../../../softbot/api";
|
||||
// import Avatar from './UpdateAvatarModal';
|
||||
import UploadImage from '../../../../../../forge/Team/Component/UploadImage.jsx'
|
||||
// 修改Bot
|
||||
function BasicInformation(props){
|
||||
const {form} = props;
|
||||
const {form, botDetail, match:{params:{id}}, setReload, current_user} = props;
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||
const [ content , setContent ] = useState(undefined);
|
||||
const [ avatarVisible , setAvatarVisible ] = useState(false);
|
||||
const [ image , setImage ] = useState(undefined);
|
||||
const [ imageFlag , setImageFlag ] = useState(false);
|
||||
const [ imageId, setImageId] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
console.log('111');
|
||||
window.scrollTo(0, 0);
|
||||
console.log('222');
|
||||
},[])
|
||||
function onCancelAvatar(){
|
||||
setAvatarVisible(false);
|
||||
}
|
||||
|
||||
function getImage(image){
|
||||
setImageFlag(true);
|
||||
setImage(image);
|
||||
}
|
||||
|
||||
function getImageId(id){
|
||||
setImageId(id);
|
||||
}
|
||||
|
||||
function onContentChange(value){
|
||||
setContent(value);
|
||||
};
|
||||
// 注册新的bot
|
||||
|
||||
useEffect(()=>{
|
||||
if(botDetail){
|
||||
setContent(botDetail.bot_des);
|
||||
setImage(botDetail.logo)
|
||||
}
|
||||
},[botDetail])
|
||||
|
||||
// 修改Bot
|
||||
function submit(e){
|
||||
e.preventDefault();
|
||||
validateFields((err, fieldsValue)=>{
|
||||
if(err){
|
||||
return;
|
||||
}
|
||||
console.log('fieldsValue', fieldsValue);
|
||||
const params = {
|
||||
...botDetail,
|
||||
...fieldsValue,
|
||||
bot_id: parseInt(id),
|
||||
logo: imageId ? '/api/attachments/'+imageId : '/api/attachments/347240'
|
||||
}
|
||||
registerUpdateBot(params).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success("更改成功");
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
return <Box>
|
||||
<div className="basicInformationBox">
|
||||
{botDetail && <div className="basicInformationBox">
|
||||
<p className="informationHead pb15 mb10">注册信息</p>
|
||||
<div className="labelBox"><span className="label">Bot所有者</span>59897989liccha</div>
|
||||
<div className="labelBox"><span className="label">Bot ID</span>4989895</div>
|
||||
<div className="labelBox"><span className="label">客户端ID</span>xdeeqwerrqqrfrrrrrrr</div>
|
||||
<div className="labelBox"><span className="label">主页URL</span>https://www.gitlink.org.cn/xiaoxiazi/organizes</div>
|
||||
<div className="labelBox"><span className="label">Bot ID</span>{id}</div>
|
||||
<div className="labelBox"><span className="label">客户端ID</span>{botDetail.client_id}</div>
|
||||
<div className="labelBox"><span className="label">主页URL</span><Link to={`/softbot/${id}`} className="blueSpan">{window.location.origin + `/softbot/${id}`}</Link></div>
|
||||
<div className="informationHead disFlex pb15 mt20 mb10">
|
||||
客户端密钥
|
||||
<Button className="themeCorBorBut">生成密钥</Button>
|
||||
|
@ -56,14 +89,15 @@ function BasicInformation(props){
|
|||
<p className="informationHead mt30 pb15">Bot信息</p>
|
||||
<Form className="basicInformationForm mt10" onSubmit={submit}>
|
||||
<Form.Item label="Bot名称" className="width80 botItem">
|
||||
{getFieldDecorator("title",{
|
||||
rules:[{required:true,message:"请输入Bot名称"}]
|
||||
{getFieldDecorator("bot_name",{
|
||||
rules:[{required:true,message:"请输入Bot名称"}],
|
||||
initialValue: botDetail.bot_name
|
||||
})(
|
||||
<Input placeholder="请输入Bot名称" maxLength={200} className="height36"/>
|
||||
<Input.TextArea placeholder="请输入Bot名称" maxLength={200} className="height36" autoSize={true}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="详细介绍" className="botItem introduce">
|
||||
{getFieldDecorator("key",{
|
||||
{getFieldDecorator("bot_des",{
|
||||
rules:[]
|
||||
})(
|
||||
<MDEditor
|
||||
|
@ -78,19 +112,29 @@ function BasicInformation(props){
|
|||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="Webhook地址" className="width80 botItem">
|
||||
{getFieldDecorator("title1",{
|
||||
rules:[{required:true,message:"请输入Webhook地址"}]
|
||||
{getFieldDecorator("webhook",{
|
||||
rules:[{required:true,message:"请输入Webhook地址"}],
|
||||
initialValue: botDetail.webhook
|
||||
})(
|
||||
<Input placeholder="请输入Webhook地址" maxLength={200} className="height36"/>
|
||||
<Input.TextArea placeholder="请输入Webhook地址" maxLength={200} className="height36" autoSize={true}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item className="mt30"><Button style={{width:"129px", height: '36px'}} type="primary" htmlType="submit">保存修改</Button></Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</div>}
|
||||
<div className="headPortraitBox">
|
||||
<img src="" alt="" className="headPortrait"/>
|
||||
<Button className="themeCorBorBut">修改头像</Button>
|
||||
<UploadImage url={image && image.startsWith('/api/attachments/') ? getImageUrl(`/${image}`) : image} getImage={getImage} getImageId = {getImageId}/>
|
||||
<Button className="themeCorBorBut ml5">修改头像</Button>
|
||||
</div>
|
||||
{/* {
|
||||
avatarVisible &&
|
||||
<Avatar
|
||||
onCancel={onCancelAvatar}
|
||||
avatarImg={getImageUrl(`/${current_user && current_user.image_url}`)}
|
||||
id={current_user && current_user.user_id}
|
||||
botDetail={botDetail}
|
||||
/>
|
||||
} */}
|
||||
</Box>
|
||||
}
|
||||
export default Form.create()(BasicInformation);
|
|
@ -11,6 +11,9 @@
|
|||
.labelBox{
|
||||
line-height: 40px;
|
||||
}
|
||||
.blueSpan{
|
||||
color: $primary-color;
|
||||
}
|
||||
.label{
|
||||
display: inline-block;
|
||||
width: 76px;
|
||||
|
@ -61,6 +64,17 @@
|
|||
padding: 15px 0;
|
||||
border-bottom: 1px dashed #e0e6f5;
|
||||
}
|
||||
.transferBotStatus{
|
||||
background-color:rgba(70, 106, 255, 0.09);
|
||||
border:1px solid $primary-color;
|
||||
border-radius:4px;
|
||||
color:rgba(0, 0, 0, 0.65);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.icon-yuyue-lishi-shijian{
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
.themeHeadModal{
|
||||
.ant-modal-header{
|
||||
|
@ -83,6 +97,7 @@
|
|||
.ant-modal-body{
|
||||
background-image:linear-gradient(42.46deg,#ffffff 0%,#ffffff 48.54%,#ebf0ff 100%);
|
||||
}
|
||||
.makeOverErrorTip{color:#f60011;}
|
||||
}
|
||||
.putawayBox{
|
||||
width: 100%;
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import React from "react";
|
||||
import { Button, Checkbox, Form, Input, Select } from "antd";
|
||||
import { Button, Checkbox, Form, Input, message, Select } from "antd";
|
||||
import { useState } from "react";
|
||||
import '../../new/index.scss';
|
||||
import './index.scss';
|
||||
import { registerUpdateBot } from "../../../../../../softbot/api";
|
||||
const {Option} = Select;
|
||||
// 注册一个新的Bot
|
||||
function Jurisdiction(props){
|
||||
const {form} = props;
|
||||
const {form, botDetail, setReload, match:{params:{id}}} = props;
|
||||
const {getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||
const resource = [{value: '0', name: '无权限'}, {value: '1', name: '只读'}, {value: '2', name: '读写'}];
|
||||
const [ codeSelectValue , setCodeSelectValue ] = useState(resource[0].value);
|
||||
const [ prSelectValue , setPrSelectValue ] = useState(resource[0].value);
|
||||
const resource = [{value: 2, name: '无权限'}, {value: 0, name: '只读'}, {value: 1, name: '读写'}];
|
||||
const [codeSelectValue , setCodeSelectValue ] = useState(botDetail && botDetail.limit_and_events.juris_diction_code);
|
||||
const [prSelectValue , setPrSelectValue ] = useState(botDetail && botDetail.limit_and_events.juris_diction_pr);
|
||||
|
||||
function codeControl(e){
|
||||
setCodeSelectValue(e);
|
||||
|
@ -29,14 +30,31 @@ function Jurisdiction(props){
|
|||
if(err){
|
||||
return;
|
||||
}
|
||||
console.log('fieldsValue', fieldsValue);
|
||||
const {juris_diction_code, juris_diction_pr, event_code, event_pr} = fieldsValue;
|
||||
const params = {
|
||||
...botDetail,
|
||||
bot_id: parseInt(id),
|
||||
limit_and_events: {
|
||||
event_code: event_code ? event_code.toString() : "",
|
||||
event_pr: event_pr ? event_pr.toString() : "",
|
||||
juris_diction_code,
|
||||
juris_diction_pr
|
||||
},
|
||||
}
|
||||
registerUpdateBot(params).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success("更改成功");
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
return <Form className="createExploitForm jurisdictionBox" onSubmit={submit}>
|
||||
{botDetail && <div>
|
||||
<div className="resourceTitle font-16 pb15 mb10">仓库访问权限</div>
|
||||
<Form.Item label="代码库权限" className="resourceBox botItem dashedBorder">
|
||||
<div className="color-99">代码库git推送、分支的创建与删除</div>
|
||||
{getFieldDecorator("resource1",{initialValue: resource[0].value, getValueFromEvent: codeControl})(
|
||||
{getFieldDecorator("juris_diction_code",{initialValue: botDetail.limit_and_events.juris_diction_code, getValueFromEvent: codeControl})(
|
||||
<Select>
|
||||
{resource.map(item=>{return <Option value={item.value} key={item.value}>{item.name}</Option>})}
|
||||
</Select>
|
||||
|
@ -45,7 +63,7 @@ function Jurisdiction(props){
|
|||
<div className="dashedBor"></div>
|
||||
<Form.Item label="合并请求(PR)权限" className="resourceBox botItem">
|
||||
<div className="color-99">合并请求的打开、关闭、编辑、分配</div>
|
||||
{getFieldDecorator("resource2",{initialValue: resource[0].value, getValueFromEvent: prControl})(
|
||||
{getFieldDecorator("juris_diction_pr",{initialValue: botDetail.limit_and_events.juris_diction_pr, getValueFromEvent: prControl})(
|
||||
<Select>
|
||||
{resource.map(item=>{return <Option value={item.value} key={item.value}>{item.name}</Option>})}
|
||||
</Select>
|
||||
|
@ -53,7 +71,7 @@ function Jurisdiction(props){
|
|||
</Form.Item>
|
||||
{(codeSelectValue !== resource[0].value || prSelectValue !== resource[0].value) && <div className="resourceTitle font-16 pb15 mb10">订阅事件</div>}
|
||||
{codeSelectValue !== resource[0].value && <Form.Item label="代码库事件" className="botItem width50 checkBox three dashedBorder">
|
||||
{getFieldDecorator("title2")(
|
||||
{getFieldDecorator("event_code", {initialValue: botDetail.limit_and_events.event_code})(
|
||||
<Checkbox.Group>
|
||||
<Checkbox value={0}>推送<br/><span className="color-99">git推送到存储库</span></Checkbox>
|
||||
<Checkbox value={1}>创建<br/><span className="color-99">创建分支或标签</span></Checkbox>
|
||||
|
@ -63,14 +81,14 @@ function Jurisdiction(props){
|
|||
</Form.Item>}
|
||||
{(codeSelectValue !== resource[0].value && prSelectValue !== resource[0].value) && <div className="dashedBor"></div>}
|
||||
{prSelectValue !== resource[0].value && <Form.Item label="合并请求事件" className="botItem width50 checkBox">
|
||||
{getFieldDecorator("title5")(
|
||||
{getFieldDecorator("event_pr", {initialValue: botDetail.limit_and_events.event_pr})(
|
||||
<Checkbox.Group>
|
||||
<Checkbox value={0}>合并请求<br/><span className="color-99">合并请求被打开、被关闭、被重新打开或被编辑</span></Checkbox>
|
||||
<Checkbox value={1}>合并请求分配<br/><span className="color-99">合并请求被分配或取消分配</span></Checkbox>
|
||||
<Checkbox value={3}>合并请求<br/><span className="color-99">合并请求被打开、被关闭、被重新打开或被编辑</span></Checkbox>
|
||||
<Checkbox value={4}>合并请求分配<br/><span className="color-99">合并请求被分配或取消分配</span></Checkbox>
|
||||
</Checkbox.Group>
|
||||
)}
|
||||
</Form.Item>}
|
||||
<Form.Item className="mt30"><Button style={{width:"129px", height: '36px'}} type="primary" htmlType="submit">保存修改</Button></Form.Item>
|
||||
<Form.Item className="mt30"><Button style={{width:"129px", height: '36px'}} type="primary" htmlType="submit">保存修改</Button></Form.Item></div>}
|
||||
</Form>
|
||||
}
|
||||
export default Form.create()(Jurisdiction);
|
|
@ -1,16 +1,62 @@
|
|||
import React, {forwardRef, useState} from "react";
|
||||
import { Button, Checkbox, Form, Input, Select } from "antd";
|
||||
import React, {forwardRef, useState, useEffect} from "react";
|
||||
import { Button, Checkbox, Form, Input, message, Select } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import './index.scss';
|
||||
import MdEditor from "../../../../../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import { marketBot, getAllBotCategory, getMarketBotById, updateMarketBot } from "../../../../../../softbot/api";
|
||||
import moment from "moment";
|
||||
const {Option} = Select;
|
||||
|
||||
function Putaway(props){
|
||||
const {form} = props;
|
||||
const {form, current_user, match:{params:{id}}, botDetail, location:{pathname}} = props;
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||
const resource = [{value: '0', name: '项目管理'}, {value: '1', name: '代码管理'}, {value: '2', name: '测试部署'}, {value: '3', name: '其他'}];
|
||||
const [ resource, setResource] = useState([]);
|
||||
const [ resourceFirst, setResourceFirst] = useState([]);
|
||||
const [ resourceSecond, setResourceSecond] = useState([]);
|
||||
const [ content , setContent ] = useState(undefined);
|
||||
const [ disabled , setDisabled ] = useState(undefined);
|
||||
const [ detail, setDetail] = useState(undefined);
|
||||
const [ isEdit, setIsEdit] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
// 获取分类列表
|
||||
getAllBotCategory().then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setResource(res.data.category_list);
|
||||
setResourceFirst(res.data.category_list);
|
||||
setResourceSecond(res.data.category_list);
|
||||
}
|
||||
})
|
||||
if(pathname && pathname.endsWith("/putaway/edit")){
|
||||
setIsEdit(true);
|
||||
setDisabled(true);
|
||||
getMarketBotById({bot_id: id}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setDetail({
|
||||
...res.data
|
||||
});
|
||||
setContent(res.data.market_intro);
|
||||
}
|
||||
})
|
||||
}else{
|
||||
setIsEdit(false);
|
||||
if(botDetail){
|
||||
const {bot_des, bot_name, webhook} = botDetail;
|
||||
setDetail({
|
||||
bot_id: id,
|
||||
category: "",
|
||||
first_func: undefined,
|
||||
logo: "",
|
||||
market_desc: undefined,
|
||||
market_name: bot_name,
|
||||
market_time: undefined,
|
||||
second_func: undefined,
|
||||
webhook: webhook
|
||||
})
|
||||
setContent(bot_des);
|
||||
}
|
||||
}
|
||||
}, [pathname, botDetail])
|
||||
|
||||
// 监听同意协议
|
||||
function onChange(e){
|
||||
|
@ -28,48 +74,94 @@ function Putaway(props){
|
|||
if(err){
|
||||
return;
|
||||
}
|
||||
const {logo} = botDetail;
|
||||
if(isEdit){
|
||||
// 更改bot上架信息
|
||||
updateMarketBot({
|
||||
...fieldsValue,
|
||||
category: "",
|
||||
is_receive_ag1: 1,
|
||||
is_receive_ag2: 0,
|
||||
logo: logo,
|
||||
market_time: "",
|
||||
user_id: current_user && current_user.user_id,
|
||||
bot_id: parseInt(id),
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success("修改成功");
|
||||
}else{
|
||||
message.error(res.data);
|
||||
}
|
||||
})
|
||||
}else{
|
||||
// 上架bot
|
||||
marketBot({
|
||||
...fieldsValue,
|
||||
user_id: current_user && current_user.user_id,
|
||||
bot_id: parseInt(id),
|
||||
category: "",
|
||||
is_receive_ag1: disabled ? 1 : 0,
|
||||
is_receive_ag2: 0,
|
||||
logo: logo,
|
||||
market_time: moment().format(),
|
||||
}).then(res=>{
|
||||
if(res && res.code === -1){
|
||||
message.error(res.data);
|
||||
}else{
|
||||
message.success("成功上架市场");
|
||||
props.history.push('/settings/dispositionBot');
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return <div className="putawayBox">
|
||||
<div className="putaHead pb10 font-18 mb5">
|
||||
<a href="#" className="font-16">高级选项></a><b>上架Bot市场</b>
|
||||
</div>
|
||||
<Form className="putawayForm" onSubmit={submit}>
|
||||
{detail && <Form className="putawayForm" onSubmit={submit}>
|
||||
<Form.Item label="上架Bot市场名称" className="width50 oneItem">
|
||||
{getFieldDecorator("a",{
|
||||
rules:[{required:true,message:"请输入上架Bot市场名称"}]
|
||||
{getFieldDecorator("market_name",{
|
||||
rules:[{required:true,message:"请输入上架Bot市场名称"}],
|
||||
initialValue: detail.market_name
|
||||
})(
|
||||
<Input placeholder="请输入上架Bot市场名称" maxLength={200} className="height36"/>
|
||||
<Input.TextArea placeholder="请输入上架Bot市场名称" maxLength={200} className="height36" autoSize={true}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="简要介绍" className="oneItem">
|
||||
{getFieldDecorator("b",{
|
||||
rules:[{required:true,message:"请输入简要介绍"}]
|
||||
{getFieldDecorator("market_desc",{
|
||||
rules:[{required:true,message:"请输入简要介绍"}],
|
||||
initialValue: detail.market_desc
|
||||
})(
|
||||
<Input.TextArea placeholder="请输入简要介绍的内容" maxLength={50} className="height36"/>
|
||||
<Input.TextArea placeholder="请输入简要介绍的内容" maxLength={200} className="height36" autoSize={true}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<div className="selectBox">
|
||||
<Form.Item label="主要功能" className="selectOne oneItem">
|
||||
{getFieldDecorator("c",{
|
||||
rules:[{required:true,message:"请选择主要功能"}]
|
||||
{getFieldDecorator("first_func",{
|
||||
rules:[{required:true,message:"请选择主要功能"}],
|
||||
initialValue: detail.first_func
|
||||
})(
|
||||
<Select placeholder="请选择">
|
||||
{resource.map(item=>{return <Option value={item.value} key={item.value}>{item.name}</Option>})}
|
||||
<Select placeholder="请选择" onChange={(value)=>{setResourceSecond(resource.filter(item => item !== value))}}>
|
||||
{resourceFirst.map(item=>{return <Option value={item} key={item}>{item}</Option>})}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="次要功能" className="selectOne oneItem">
|
||||
{getFieldDecorator("d")(
|
||||
<Select placeholder="请选择">
|
||||
{resource.map(item=>{return <Option value={item.value} key={item.value}>{item.name}</Option>})}
|
||||
{getFieldDecorator("second_func",{
|
||||
initialValue: detail.second_func
|
||||
})(
|
||||
<Select placeholder="请选择" onChange={(value)=>{setResourceFirst(resource.filter(item => item !== value))}}>
|
||||
{resourceSecond.map(item=>{return <Option value={item} key={item}>{item}</Option>})}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
<Form.Item label="详细介绍" className="oneItem introduce">
|
||||
{getFieldDecorator("e",{
|
||||
rules:[{required:true,message:"请输入详细介绍"}]
|
||||
{getFieldDecorator("market_intro",{
|
||||
rules:[{required:true,message:"请输入详细介绍"}],
|
||||
initialValue: content
|
||||
})(
|
||||
<MdEditor
|
||||
placeholder={"请输入详细介绍"}
|
||||
|
@ -82,17 +174,18 @@ function Putaway(props){
|
|||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="订阅接收Webhook地址" className="width50 oneItem">
|
||||
{getFieldDecorator("f",{
|
||||
rules:[{required:true,message:"请输入Webhook地址"}]
|
||||
{getFieldDecorator("webhook",{
|
||||
rules:[{required:true,message:"请输入Webhook地址"}],
|
||||
initialValue: detail.webhook
|
||||
})(
|
||||
<Input placeholder="请输入Webhook地址" maxLength={200} className="height36"/>
|
||||
<Input.TextArea placeholder="请输入Webhook地址" maxLength={200} className="height36" autoSize={true}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{!isEdit && <Form.Item>
|
||||
<Checkbox onChange={onChange}>我接受GitLink Bot市场开发者协议</Checkbox>
|
||||
</Form.Item>
|
||||
<Form.Item><Button style={{width:"129px", height: '36px'}} type="primary" htmlType="submit" disabled={!disabled} className="putawayBut">申请上架</Button></Form.Item>
|
||||
</Form>
|
||||
</Form.Item>}
|
||||
<Form.Item><Button style={{width:"129px", height: '36px'}} type="primary" htmlType="submit" disabled={!disabled} className="putawayBut mt20">{isEdit ? '保存修改' : '申请上架'}</Button></Form.Item>
|
||||
</Form>}
|
||||
</div>
|
||||
}
|
||||
export default Form.create()(forwardRef(Putaway));
|
|
@ -1,4 +1,4 @@
|
|||
import React, {useEffect} from "react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import Loadable from "react-loadable";
|
||||
import Loading from "../../../../../Loading";
|
||||
|
@ -7,6 +7,7 @@ import { TPMIndexHOC } from "../../../../../modules/tpm/TPMIndexHOC";
|
|||
import { Box } from "../../../../Component/layout";
|
||||
import './index.scss';
|
||||
import { Button } from "antd";
|
||||
import { getRegisterBot } from "../../../../../softbot/api";
|
||||
|
||||
const BasicInformation = Loadable({
|
||||
loader: () => import("./compenent/basicInformation"),
|
||||
|
@ -27,10 +28,21 @@ const Putaway = Loadable({
|
|||
|
||||
// 对自己注册的bot进行配置页面
|
||||
function ConfigurateBot(props){
|
||||
const {match} = props;
|
||||
const { pathname } = props.location;
|
||||
const {params:{id}} = match;
|
||||
console.log('444', id, props);
|
||||
const {match:{params:{id}}, current_user, location:{pathname}} = props;
|
||||
const [reload, setReload] = useState(undefined);
|
||||
const [botDetail, setBotDetail] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
getRegisterBot({
|
||||
user_id: current_user && current_user.user_id,
|
||||
bot_id: id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setBotDetail(res.data.bot_output_vo);
|
||||
}
|
||||
})
|
||||
}, [reload])
|
||||
|
||||
return <div className="configurateBotBox">
|
||||
<div className="configurateBotHead mb30">
|
||||
<span className="font-18 configurateBotTitle">Bot配置</span>
|
||||
|
@ -47,24 +59,30 @@ function ConfigurateBot(props){
|
|||
<Route
|
||||
path="/settings/exploitBot/configuration/:id/advanced/putaway"
|
||||
render={(p) => (
|
||||
<Putaway {...props} {...p}/>
|
||||
<Putaway {...props} {...p} botDetail={botDetail} setReload={setReload}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/settings/exploitBot/configuration/:id/advanced/putaway/edit"
|
||||
render={(p) => (
|
||||
<Putaway {...props} {...p} botDetail={botDetail} setReload={setReload}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/settings/exploitBot/configuration/:id/basic"
|
||||
render={(p)=>(<BasicInformation {...props} {...p}/>)}
|
||||
render={(p)=>(<BasicInformation {...props} {...p} botDetail={botDetail} setReload={setReload}/>)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/settings/exploitBot/configuration/:id/jurisdiction"
|
||||
render={(p)=>(<Jurisdiction {...props} {...p}/>)}
|
||||
render={(p)=>(<Jurisdiction {...props} {...p} botDetail={botDetail} setReload={setReload}/>)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/settings/exploitBot/configuration/:id/advanced"
|
||||
render={(p)=>(<AdvancedInformation {...props} {...p}/>)}
|
||||
render={(p)=>(<AdvancedInformation {...props} {...p} botDetail={botDetail} setReload={setReload}/>)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/settings/exploitBot/configuration/:id"
|
||||
render={(p)=>(<BasicInformation {...props} {...p}/>)}
|
||||
render={(p)=>(<BasicInformation {...props} {...p} botDetail={botDetail} setReload={setReload}/>)}
|
||||
></Route>
|
||||
</Switch>
|
||||
</Box>
|
||||
|
|
|
@ -1,12 +1,70 @@
|
|||
import React from "react";
|
||||
import { Button, Icon } from "antd";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Button, Icon, message, Modal } from "antd";
|
||||
import './index.scss';
|
||||
import { Link } from "react-router-dom";
|
||||
import { useState } from "react";
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { getMyBot, getTransferToBot, receiveTransferBot, refuseTransferBot } from "../../../../softbot/api";
|
||||
import nullBot from '../../../../softbot/image/notBot.png';
|
||||
import moment from "moment";
|
||||
|
||||
function ExploitBot(props){
|
||||
const [makeOverList, setMakeOverList] = useState([{botName: 'botName', userName: 'userName', time: 'time'}, {botName: 'botName', userName: 'userName', time: 'time'}]);
|
||||
const [botList, setBotList] = useState([{botName: '此处为名称标题内容', userName: 'userName', id: '0'}, {botName: '此处为名称标题内容', userName: 'userName', id: '1'}]);
|
||||
const {current_user} = props;
|
||||
const [makeOverList, setMakeOverList] = useState([]);
|
||||
const [botList, setBotList] = useState(undefined);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [refuseBotDetail, setRefuseBotDetail] = useState(undefined);
|
||||
const [reload, setReload] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
getMyBot({
|
||||
user_id: current_user && current_user.user_id,
|
||||
page_no: 1,
|
||||
page_size: 1000
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setBotList(res.data.list);
|
||||
}
|
||||
})
|
||||
getTransferToBot({
|
||||
user_id: current_user && current_user.user_id,
|
||||
state: "2"
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setMakeOverList(res.data.bot_list);
|
||||
}
|
||||
})
|
||||
}, [reload])
|
||||
|
||||
// 接受转让的bot
|
||||
function receiveBot(info){
|
||||
receiveTransferBot({
|
||||
bot_id: info.bot_id,
|
||||
transfer_from_id: info.transfer_id,
|
||||
transfer_to_id: current_user && current_user.user_id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success('操作成功');
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 拒绝转让的bot
|
||||
function refuseBot(){
|
||||
refuseTransferBot({
|
||||
bot_id: refuseBotDetail.bot_id,
|
||||
transfer_from_bot: refuseBotDetail.transfer_id,
|
||||
transfer_to_bot: current_user && current_user.user_id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setVisible(false);
|
||||
setRefuseBotDetail(undefined);
|
||||
message.success('操作成功');
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return <div>
|
||||
<div className="exploitHead font-18">
|
||||
<span>Bot开发者配置</span>
|
||||
|
@ -14,29 +72,49 @@ function ExploitBot(props){
|
|||
</div>
|
||||
|
||||
{/* bot转让接收按钮显示区域 */}
|
||||
<div className="makeOverBox">
|
||||
{makeOverList.length > 0 && <div className="makeOverBox">
|
||||
{makeOverList.map((item, index)=>{return <div className="makeOverItem" key={index}>
|
||||
<div>
|
||||
<p className="botName font-15">{item.botName}</p>
|
||||
<p className="userName">{item.userName} {item.time}</p>
|
||||
<p className="botName font-15">{item.bot_name}</p>
|
||||
<p className="userName">{item.userName || '转让者姓名'} {moment(item.transfer_date).format('YYYY-MM-DD HH:mm')}</p>
|
||||
</div>
|
||||
<div>
|
||||
<Button className="themeCorBorBut" style={{width: '68px', height: '36px'}}>接收</Button>
|
||||
<Button className="dangerBorBut ml20" style={{width: '68px', height: '36px'}}>拒绝</Button>
|
||||
<Button className="themeCorBorBut" style={{width: '68px', height: '36px'}} onClick={()=>{receiveBot(item)}}>接收</Button>
|
||||
<Button className="dangerBorBut ml20" style={{width: '68px', height: '36px'}} onClick={()=>{setRefuseBotDetail(item); setVisible(true)}}>拒绝</Button>
|
||||
</div>
|
||||
</div>})}
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
{/* bot列表显示区域 */}
|
||||
{botList.length > 0 ? <div className="softBotListBox">
|
||||
{botList && (botList.length > 0 ? <div className="softBotListBox">
|
||||
{botList.map((item, index)=>{return <div className="softBotItem" key={index}>
|
||||
<div>
|
||||
<img src="" alt="" className="imgBox mr10"/>
|
||||
<span className="font-15">{item.botName}</span>
|
||||
<div className="botOneLine">
|
||||
<img src={getImageUrl(item.logo)} alt="" className="imgBox mr10"/>
|
||||
<span className="font-15">{item.bot_name}</span>
|
||||
</div>
|
||||
<Button className="themeCorBorBut" style={{width: '68px', height: '36px'}}><Link to={`/settings/exploitBot/configuration/${item.id}`}>编辑</Link></Button>
|
||||
<Button className="themeCorBorBut ml30" style={{width: '68px', height: '36px'}}><Link to={`/settings/exploitBot/configuration/${item.bot_id}`}>编辑</Link></Button>
|
||||
</div>})}
|
||||
</div> : <div className="font-16 softBotListBox">欢迎使用Bot! Bot可以帮助项目贡献者处理繁杂的项目任务,比如关闭疑修、合并请求。在使用之前,请先注册一个Bot</div>}
|
||||
</div> : <div className="nullBotsBox mt100">
|
||||
<img src={nullBot} alt="" width={62}/>
|
||||
<p className="font-18 showBigTip">您当前暂未注册任何Bot</p>
|
||||
<div className="showTip font-14">欢迎使用Bot! Bot可以帮助项目贡献者处理繁杂的项目任务,比如关闭疑修、合并请求。在使用之前,请先注册一个Bot!</div>
|
||||
</div>)}
|
||||
|
||||
<Modal
|
||||
className="f8HeadModal"
|
||||
width="550px"
|
||||
title={`拒绝${refuseBotDetail && refuseBotDetail.bot_name}Bot`}
|
||||
visible={visible}
|
||||
maskClosable={false}
|
||||
footer={[
|
||||
<Button onClick={()=>{setVisible(false)}} className="mr30 grayBorBut whiteBackBut" style={{width:"104px", height: '36px'}}>取消</Button>,
|
||||
<Button className="redFontBut grayBorBut whiteBackBut" style={{width:"104px", height: '36px'}} onClick={refuseBot}>确认</Button>
|
||||
]}
|
||||
onCancel={()=>{setVisible(false)}}
|
||||
>
|
||||
<div className="font-16 titleTip mt20"><span className="circleRed font-18">!</span>您确定要拒绝此Bot吗?</div>
|
||||
<div className="deleteTip">拒绝后,开发Bot权限将返回至转让人。</div>
|
||||
</Modal>
|
||||
</div>
|
||||
}
|
||||
export default ExploitBot;
|
|
@ -60,7 +60,22 @@
|
|||
.imgBox{
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background-color: yellow;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.nullBotsBox{
|
||||
border-radius: 4px 4px 0px 0px;
|
||||
text-align: center;
|
||||
padding: 25px 158px 65px;
|
||||
.showBigTip{
|
||||
color:#333333;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 22px !important;
|
||||
}
|
||||
.showTip{color: #666;}
|
||||
}
|
||||
.botOneLine{
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
|
@ -1,14 +1,15 @@
|
|||
import React, { forwardRef, useState } from "react";
|
||||
import { Button, Checkbox, Form, Input, Select } from "antd";
|
||||
import { Button, Checkbox, Form, Input, message, Radio, Select } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import MDEditor from '../../../../../modules/tpm/challengesnew/tpm-md-editor';
|
||||
import './index.scss';
|
||||
import { registerBot } from "../../../../../softbot/api";
|
||||
const {Option} = Select;
|
||||
|
||||
function Disposition(props){
|
||||
const {form} = props;
|
||||
const {form, current_user} = props;
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||
const resource = [{value: '0', name: '无权限'}, {value: '1', name: '只读'}, {value: '2', name: '读写'}];
|
||||
const resource = [{value: 2, name: '无权限'}, {value: 0, name: '只读'}, {value: 1, name: '读写'}];
|
||||
|
||||
const [ content , setContent ] = useState(undefined);
|
||||
const [ codeSelectValue , setCodeSelectValue ] = useState(resource[0].value);
|
||||
|
@ -35,7 +36,26 @@ function Disposition(props){
|
|||
if(err){
|
||||
return;
|
||||
}
|
||||
console.log('fieldsValue', fieldsValue);
|
||||
const {bot_name, bot_des, webhook, is_public, juris_diction_code, juris_diction_pr, event_code, event_pr} = fieldsValue;
|
||||
const param = {
|
||||
bot_name, bot_des, webhook, is_public,
|
||||
user_id: current_user && current_user.user_id,
|
||||
logo: '/api/attachments/347240',
|
||||
limit_and_events: {
|
||||
event_code: event_code ? event_code.toString() : "",
|
||||
event_pr: event_pr ? event_pr.toString() : "",
|
||||
juris_diction_code,
|
||||
juris_diction_pr
|
||||
},
|
||||
}
|
||||
registerBot(param).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success('注册成功');
|
||||
props.history.push('/settings/exploitBot/configuration/'+res.data.bot_id);
|
||||
}else{
|
||||
message.success('注册失败: '+res.data);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -45,14 +65,14 @@ function Disposition(props){
|
|||
</div>
|
||||
<Form className="createExploitForm" onSubmit={submit}>
|
||||
<Form.Item label="Bot名称" className="width50 botItem">
|
||||
{getFieldDecorator("title",{
|
||||
{getFieldDecorator("bot_name",{
|
||||
rules:[{required:true,message:"请输入Bot名称"}]
|
||||
})(
|
||||
<Input placeholder="请输入Bot名称" maxLength={200} className="height36"/>
|
||||
<Input.TextArea placeholder="请输入Bot名称" maxLength={200} className="height36" autoSize={true}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="详细介绍" className="botItem introduce">
|
||||
{getFieldDecorator("key",{
|
||||
{getFieldDecorator("bot_des",{
|
||||
rules:[]
|
||||
})(
|
||||
<MDEditor
|
||||
|
@ -66,16 +86,16 @@ function Disposition(props){
|
|||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="Webhook地址" className="width50 botItem">
|
||||
{getFieldDecorator("title1",{
|
||||
{getFieldDecorator("webhook",{
|
||||
rules:[{required:true,message:"请输入Webhook地址"}]
|
||||
})(
|
||||
<Input placeholder="请输入Webhook地址" maxLength={200} className="height36"/>
|
||||
<Input.TextArea placeholder="请输入Webhook地址" maxLength={200} className="height36" autoSize={true}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<div className="resourceTitle font-16 pb15 mb10">仓库访问权限</div>
|
||||
<Form.Item label="代码库权限" className="resourceBox botItem dashedBorder">
|
||||
<div className="color-99">代码库git推送、分支的创建与删除</div>
|
||||
{getFieldDecorator("resource1",{initialValue: resource[0].value, getValueFromEvent: codeControl})(
|
||||
{getFieldDecorator("juris_diction_code",{initialValue: resource[0].value, getValueFromEvent: codeControl})(
|
||||
<Select>
|
||||
{resource.map(item=>{return <Option value={item.value} key={item.value}>{item.name}</Option>})}
|
||||
</Select>
|
||||
|
@ -84,7 +104,7 @@ function Disposition(props){
|
|||
<div className="dashedBor"></div>
|
||||
<Form.Item label="合并请求(PR)权限" className="resourceBox botItem">
|
||||
<div className="color-99">合并请求的打开、关闭、编辑、分配</div>
|
||||
{getFieldDecorator("resource2",{initialValue: resource[0].value, getValueFromEvent: prControl})(
|
||||
{getFieldDecorator("juris_diction_pr",{initialValue: resource[0].value, getValueFromEvent: prControl})(
|
||||
<Select>
|
||||
{resource.map(item=>{return <Option value={item.value} key={item.value}>{item.name}</Option>})}
|
||||
</Select>
|
||||
|
@ -92,7 +112,7 @@ function Disposition(props){
|
|||
</Form.Item>
|
||||
{(codeSelectValue !== resource[0].value || prSelectValue !== resource[0].value) && <div className="resourceTitle font-16 pb15 mb10">订阅事件</div>}
|
||||
{codeSelectValue !== resource[0].value && <Form.Item label="代码库事件" className="botItem width50 checkBox three dashedBorder">
|
||||
{getFieldDecorator("title2")(
|
||||
{getFieldDecorator("event_code")(
|
||||
<Checkbox.Group>
|
||||
<Checkbox value={0}>推送<br/><span className="color-99">git推送到存储库</span></Checkbox>
|
||||
<Checkbox value={1}>创建<br/><span className="color-99">创建分支或标签</span></Checkbox>
|
||||
|
@ -102,19 +122,19 @@ function Disposition(props){
|
|||
</Form.Item>}
|
||||
{(codeSelectValue !== resource[0].value && prSelectValue !== resource[0].value) && <div className="dashedBor"></div>}
|
||||
{prSelectValue !== resource[0].value && <Form.Item label="合并请求事件" className="botItem width50 checkBox">
|
||||
{getFieldDecorator("title5")(
|
||||
{getFieldDecorator("event_pr")(
|
||||
<Checkbox.Group>
|
||||
<Checkbox value={0}>合并请求<br/><span className="color-99">合并请求被打开、被关闭、被重新打开或被编辑</span></Checkbox>
|
||||
<Checkbox value={1}>合并请求分配<br/><span className="color-99">合并请求被分配或取消分配</span></Checkbox>
|
||||
<Checkbox value={3}>合并请求<br/><span className="color-99">合并请求被打开、被关闭、被重新打开或被编辑</span></Checkbox>
|
||||
<Checkbox value={4}>合并请求分配<br/><span className="color-99">合并请求被分配或取消分配</span></Checkbox>
|
||||
</Checkbox.Group>
|
||||
)}
|
||||
</Form.Item>}
|
||||
<Form.Item label="公/私有设置" className="botItem resourceTitleItem">
|
||||
{getFieldDecorator("title3")(
|
||||
<Checkbox.Group>
|
||||
<Checkbox value={0}>公开</Checkbox>
|
||||
<Checkbox value={1}>私有</Checkbox>
|
||||
</Checkbox.Group>
|
||||
{getFieldDecorator("is_public")(
|
||||
<Radio.Group>
|
||||
<Radio value={1}>公开</Radio>
|
||||
<Radio value={0}>私有</Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item><Button style={{width:"129px", height: '36px'}} type="primary" htmlType="submit">注册Bot</Button></Form.Item>
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
justify-content: space-between;
|
||||
position: relative;
|
||||
}
|
||||
.resourceBox .ant-select{
|
||||
width: auto;
|
||||
}
|
||||
.width50{
|
||||
width: 60%;
|
||||
&.checkBox{
|
||||
|
|
|
@ -315,7 +315,6 @@
|
|||
.imgBox{
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background-color: yellow;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,21 +3,36 @@ import { Link } from "react-router-dom";
|
|||
import { Button } from "antd";
|
||||
import nullBot from '../../softbot/image/notBot.png';
|
||||
import './setting.scss';
|
||||
import { useEffect } from "react";
|
||||
import { getStoreAllInstallBots } from "../../softbot/api";
|
||||
import { getImageUrl } from 'educoder';
|
||||
|
||||
function SoftBot(props){
|
||||
const {projectDetail} = props;
|
||||
const [botList, setBotList] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
// 获取仓库安装的所有bot
|
||||
projectDetail && getStoreAllInstallBots({
|
||||
store_id: projectDetail.project_id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setBotList(res.data.install_bot_infos);
|
||||
}
|
||||
})
|
||||
}, [projectDetail])
|
||||
|
||||
function SoftBot(){
|
||||
// {botName: '此处为名称标题内容', status: '0', id: '0'}, {botName: '此处为名称标题内容', status: '1', id: '1'}
|
||||
const [botList, setBotList] = useState([]);
|
||||
return <div className="softBotClass">
|
||||
<div className="softBoxHeadTitle font-18">Bot安装</div>
|
||||
{/* bot列表显示区域 */}
|
||||
{botList.length > 0 ? <div className="botListBox">
|
||||
{botList && (botList.length > 0 ? <div className="botListBox">
|
||||
{botList.map((item, index)=>{return <div className="disBotItem" key={index}>
|
||||
<div>
|
||||
<img src="" alt="" className="imgBox mr20"/>
|
||||
<span className="font-15">{item.botName}</span>
|
||||
<span className={`statusBox font-12 ml10 ${item.status === '0' ? 'active' : ''}`}>{item.status === '0' ? '启用' : '挂起'}</span>
|
||||
<img src={getImageUrl(item.logo)} alt="" className="imgBox mr20"/>
|
||||
<span className="font-15">{item.bot_name}</span>
|
||||
<span className={`statusBox font-12 ml10 ${item.state === 0 ? '' : 'active'}`}>{item.state === 0 ? '挂起' : '启用'}</span>
|
||||
</div>
|
||||
<Button className="themeCorBorBut" style={{width: '68px', height: '36px'}}><Link to={`/settings/dispositionBot/${item.id}`}>配置</Link></Button>
|
||||
<Button className="themeCorBorBut" style={{width: '68px', height: '36px'}}><Link to={`/settings/dispositionBot/${item.bot_id}`}>配置</Link></Button>
|
||||
</div>})}
|
||||
</div> : <div className="nullBotBox mt20">
|
||||
<img src={nullBot} alt="" width={62}/>
|
||||
|
@ -25,7 +40,7 @@ function SoftBot(){
|
|||
<div className="showTip font-14">Bot可以帮助项目贡献者处理繁杂的项目任务,比如关闭疑修、合并请求等,以节约时间精力提升开发效率。快去市场中挑选一个适合您项目的Bot吧!</div>
|
||||
<div className="borTip"></div>
|
||||
<Button type="primary" style={{width: '112px', height: '36px', padding: 0}}><Link to={'/softbot'}>去Bot市场逛逛</Link></Button>
|
||||
</div>}
|
||||
</div>)}
|
||||
</div>
|
||||
}
|
||||
export default SoftBot
|
|
@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
|
|||
import { Upload , Icon , message } from "antd";
|
||||
import { getUploadActionUrl } from 'educoder';
|
||||
|
||||
function UploadImage({ getImage , url }){
|
||||
function UploadImage({ getImage , url, getImageId }){
|
||||
const [ imageUrl , setImageUrl ] = useState(undefined);
|
||||
useEffect(()=>{
|
||||
if(url){
|
||||
|
@ -33,6 +33,8 @@ function UploadImage({ getImage , url }){
|
|||
// 上传完成后
|
||||
function handleChange(info){
|
||||
if(info && info.file && info.file.status === "done"){
|
||||
console.log('info', info);
|
||||
getImageId && getImageId(info.file.response.id);
|
||||
getBase64(info.file.originFileObj, imageUrl =>
|
||||
setImageUrl(imageUrl)
|
||||
);
|
||||
|
|
|
@ -68,7 +68,6 @@ export default function javaFetch(actionUrl){
|
|||
}
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
let res = error.response||{};
|
||||
if (res.status === 400) {
|
||||
message.error(res.data.message || '操作失败');
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'cropperjs/dist/cropper.css';
|
|||
import axios from 'axios';
|
||||
|
||||
function Index({onCancel,avatarImg,login}){
|
||||
console.log('avatarImg,login', avatarImg,login);
|
||||
|
||||
const [ avatarPhoto , setAvatarPhoto ] = useState(avatarImg);
|
||||
|
||||
|
|
|
@ -74,8 +74,8 @@ function md_elocalStorage(editor, mdu, id) {
|
|||
return tid
|
||||
}
|
||||
|
||||
export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch, showNullButton = false, showResizeBar = false, startInit = true , forMember = true , isCanAtme = false , changeAtWhoLoginList, owner, projectsId }) => {
|
||||
|
||||
// isFocus:是否聚焦到md编译器
|
||||
export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch, showNullButton = false, showResizeBar = false, startInit = true , forMember = true , isCanAtme = false , changeAtWhoLoginList, owner, projectsId, isFocus = true }) => {
|
||||
const editorEl = useRef();
|
||||
const resizeBarEl = useRef();
|
||||
const [editorInstance, setEditorInstance] = useState();
|
||||
|
@ -114,7 +114,7 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla
|
|||
if (entry.target.offsetHeight > 0 || entry.target.offsetWidth > 0) {
|
||||
editorInstance.resize();
|
||||
editorInstance.cm.refresh();
|
||||
editorInstance.cm.focus();
|
||||
isFocus && editorInstance.cm.focus();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,19 +1,217 @@
|
|||
import fetch from './fetch';
|
||||
|
||||
// 获取当前用户项目报名信息
|
||||
// export function getAllBotCategory(params) {
|
||||
// return fetch({
|
||||
// url: `/getAllBotCategory`,
|
||||
// method: 'get',
|
||||
// params
|
||||
// });
|
||||
// }
|
||||
|
||||
//报名夏令营
|
||||
export function getAllBotCategory(data) {
|
||||
// 获取个人注册Bot
|
||||
export function getMyBot(params) {
|
||||
return fetch({
|
||||
url: '/getAllBotCategory',
|
||||
method: 'post',
|
||||
// data: data
|
||||
url: `/getMyBot`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查看被转让的bot列表
|
||||
export function getTransferToBot(params) {
|
||||
return fetch({
|
||||
url: '/getTransferToBot',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 用户注册bot
|
||||
export function registerBot(data) {
|
||||
return fetch({
|
||||
url: '/registerBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 获取bot市场 分类列表
|
||||
export function getAllBotCategory(params) {
|
||||
return fetch({
|
||||
url: `/getAllBotCategory`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取bot市场 softbot列表
|
||||
export function getContentsLikeNameAndFunc(params) {
|
||||
return fetch({
|
||||
url: `/getContentsLikeNameAndFunc`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取bot详情
|
||||
export function getBotDetail(params) {
|
||||
return fetch({
|
||||
url: `/getBotDetail`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 用户安装bot
|
||||
export function installMarketBot(data) {
|
||||
return fetch({
|
||||
url: '/installMarketBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 接受转让的bot
|
||||
export function receiveTransferBot(data) {
|
||||
return fetch({
|
||||
url: '/receiveTransferBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 拒绝转让的bot
|
||||
export function refuseTransferBot(data) {
|
||||
return fetch({
|
||||
url: '/refuseTransferBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 获取已经安装的Bot详情信息
|
||||
export function getInstallBot(params) {
|
||||
return fetch({
|
||||
url: `/getInstallBot`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 个人删除Bot
|
||||
export function deleteBot(data) {
|
||||
return fetch({
|
||||
url: '/deleteBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 上架bot
|
||||
export function marketBot(data) {
|
||||
return fetch({
|
||||
url: '/marketBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 转让bot
|
||||
export function transferBot(data) {
|
||||
return fetch({
|
||||
url: '/transferBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 通过BotId查询MarketBot
|
||||
export function getMarketBotById(params) {
|
||||
return fetch({
|
||||
url: `/getMarketBotById`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 配置安装的Bot
|
||||
export function updateInstallBot(data) {
|
||||
return fetch({
|
||||
url: '/updateInstallBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 仓库安装的所有bot
|
||||
export function getStoreAllInstallBots(params) {
|
||||
return fetch({
|
||||
url: `/getStoreAllInstallBots`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 用户安装所有
|
||||
export function getAllInstallBots(params) {
|
||||
return fetch({
|
||||
url: `/getAllInstallBots`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 判断用户是否安装此bot
|
||||
export function judgeIsIntallBot(params) {
|
||||
return fetch({
|
||||
url: `/judgeIsIntallBot`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取注册的bot详情
|
||||
export function getRegisterBot(params) {
|
||||
return fetch({
|
||||
url: `/getRegisterBot`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 修改注册的bot信息
|
||||
export function registerUpdateBot(data) {
|
||||
return fetch({
|
||||
url: '/registerUpdateBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 更改bot上架信息
|
||||
export function updateMarketBot(data) {
|
||||
return fetch({
|
||||
url: '/updateMarketBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 下架bot
|
||||
export function downMarket(id, data) {
|
||||
return fetch({
|
||||
url: `/downMarket?id=${id}`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 卸载已经安装的bot
|
||||
export function deleteInstallBot(data) {
|
||||
return fetch({
|
||||
url: '/deleteInstallBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 取消转让
|
||||
export function cancelTransferBot(data) {
|
||||
return fetch({
|
||||
url: '/cancelTransferBot',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
|
@ -2,6 +2,7 @@ import javaFetch from '../forge/javaFetch';
|
|||
|
||||
let settings = localStorage.chromesetting && JSON.parse(localStorage.chromesetting);
|
||||
let actionUrl = settings && settings.common.softbot;
|
||||
// let actionUrl = 'http://111.8.36.180:8069';
|
||||
|
||||
const service = javaFetch(actionUrl);
|
||||
export const httpUrl = actionUrl;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
|
@ -1,24 +1,81 @@
|
|||
import { Button, Checkbox, Modal, Radio, Select } from "antd";
|
||||
import React from "react";
|
||||
import { useState } from "react";
|
||||
import style from './index.scss';
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { Button, Checkbox, message, Modal, Radio, Select } from "antd";
|
||||
import {getBotDetail, installMarketBot, judgeIsIntallBot} from '../api';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import './index.scss';
|
||||
import axios from "axios";
|
||||
|
||||
function SoftBotDEtail(props){
|
||||
const [detail, setDetail] = useState({name:'bot名称', type: '接口管理', user: '开发者昵称', intro: 'aaaaaaa', iaHas: false, detailIntro: 'aaaaaaa', img: ''});
|
||||
const [visible, setVisible] = useState(true);
|
||||
const {match:{params:{id}}, current_user} = props;
|
||||
const [detail, setDetail] = useState(undefined);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [checkValue, setCheckValue] = useState(1);
|
||||
const [selectValue, setSelectValue] = useState([]);
|
||||
const [options, setOptions] = useState(['仓库1', '仓库2仓库2仓库2仓库2仓库2仓库2仓库2', '仓库3', '仓库4', '仓库5']);
|
||||
const filterOption = options.filter(item=>!selectValue.includes(item));
|
||||
const [options, setOptions] = useState([]);
|
||||
const [filterOption, setFilterOption] = useState([]);
|
||||
const [errTip, setErrTip] = useState(undefined);
|
||||
// 是否已安装此bot
|
||||
const [isInstall, setIsInstall] = useState(false);
|
||||
const [reload, setReload] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
if(current_user && current_user.login){
|
||||
// 查询用户创建的仓库信息
|
||||
axios.get(`/users/${current_user.login}/projects.json`,{
|
||||
params:{
|
||||
limit: 1000,
|
||||
page: 1,
|
||||
category:"manage"
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setOptions(result.data.projects);
|
||||
setFilterOption(result.data.projects);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})}
|
||||
}, [])
|
||||
|
||||
useEffect(()=>{
|
||||
if(current_user && current_user.login){
|
||||
// 判断用户是否安装此bot
|
||||
judgeIsIntallBot({
|
||||
bot_id: id,
|
||||
user_id: current_user && current_user.user_id
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setIsInstall(res.data);
|
||||
}
|
||||
})}
|
||||
}, [reload])
|
||||
|
||||
useEffect(()=>{
|
||||
getBotDetail({
|
||||
bot_id: id,
|
||||
user_id: 36480
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setDetail(res.data);
|
||||
}
|
||||
})
|
||||
}, [id])
|
||||
|
||||
// 监听已选项selectValue的变化 改变下拉选择框的选择项
|
||||
useEffect(()=>{
|
||||
const ids = selectValue.map(item=>{return item.id});
|
||||
setFilterOption(options.filter(item=>!ids.includes(item.id)));
|
||||
}, [selectValue])
|
||||
|
||||
function selectChange(e){
|
||||
let newMap = selectValue;
|
||||
newMap = newMap.concat(e);
|
||||
newMap = newMap.concat(options.filter(i=>{return i.id === e})[0]);
|
||||
setSelectValue(newMap);
|
||||
}
|
||||
|
||||
function click(){
|
||||
if(detail.iaHas){
|
||||
|
||||
if(isInstall){
|
||||
props.history.push(`/settings/dispositionBot/${id}`)
|
||||
}else{
|
||||
// 安装此bot弹窗
|
||||
setVisible(true);
|
||||
|
@ -27,61 +84,87 @@ function SoftBotDEtail(props){
|
|||
|
||||
function deleteSelect(e){
|
||||
let newMap = selectValue;
|
||||
newMap = newMap.filter(item=>{return item !== e});
|
||||
newMap = newMap.filter(item=>{return item.id !== e.id});
|
||||
setSelectValue(newMap);
|
||||
}
|
||||
|
||||
function okClick(){
|
||||
|
||||
setErrTip(undefined);
|
||||
if(checkValue){
|
||||
// 至少选择一个仓库
|
||||
if(!selectValue.length){
|
||||
setErrTip('请至少选择一个仓库');
|
||||
}else{
|
||||
installBot();
|
||||
}
|
||||
}else{
|
||||
installBot();
|
||||
}
|
||||
}
|
||||
|
||||
function installBot(){
|
||||
const params = {
|
||||
"user_id":current_user.user_id,
|
||||
"bot_id":parseInt(id),
|
||||
"state":1,
|
||||
"store_list": checkValue ? selectValue.map(item=>{return item.id}) : options.map(item=>{return item.id})
|
||||
}
|
||||
installMarketBot(params).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
message.success("安装成功");
|
||||
setVisible(false);
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return <div className="softBotDetailBox">
|
||||
<div className="botDetailHead">
|
||||
{detail && <div className="botDetailHead">
|
||||
<div className="botDetailHeadCont">
|
||||
<div className="botImgBg"><img src="" alt="" className="botImg"></img></div>
|
||||
<div className="botImgBg"><img src={getImageUrl(detail.logo)} alt="" className="botImg"></img></div>
|
||||
<div className="centerBox">
|
||||
<p className="font-24">{detail.name}</p>
|
||||
<div className="userBox font-16"><span className="typeBox font-15 mr15">{detail.type}</span>{detail.user}</div>
|
||||
<div>{detail.intro}</div>
|
||||
</div>
|
||||
<Button type="primary" style={{width: '114px', height: '40px'}} className="font-15" onClick={click}>{detail.iaHas ? '查看详情' : '安装此Bot'}</Button>
|
||||
<p className="font-24">{detail.bot_name}</p>
|
||||
<div className="userBox font-16">{detail.first_func && <span className="typeBox font-15 mr15">{detail.first_func}</span>}{detail.developer_id}</div>
|
||||
<div>{detail.market_desc}</div>
|
||||
</div>
|
||||
<Button type="primary" style={{width: '114px', height: '40px'}} className="font-15" onClick={click}>{isInstall ? '查看详情' : '安装此Bot'}</Button>
|
||||
</div>
|
||||
</div>}
|
||||
<div className="detailIntroBox">
|
||||
<div className="detailIntroCont">
|
||||
<div className="detailIntroTitle font-20 mb10">Bot详细介绍</div>
|
||||
<div dangerouslySetInnerHTML={{__html: detail.detailIntro}} className="detailIntro font-15"></div>
|
||||
<div dangerouslySetInnerHTML={{__html: detail && detail.bot_des}} className="detailIntro font-15"></div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
title={<div><div className="installBotImgBox"><img img={detail.img} alt="" className="installBotImg"/></div><div className="font-18 installBotName">{detail.name}</div></div>}
|
||||
title={<div><div className="installBotImgBox"><img src={getImageUrl(detail && detail.logo)} alt="" className="installBotImg"/></div><div className="font-18 installBotName">{detail && detail.bot_name}</div></div>}
|
||||
visible={visible}
|
||||
onOk={okClick}
|
||||
onCancel={()=>{setSelectValue([]);setVisible(false)}}
|
||||
className="installBotModal"
|
||||
width={735}
|
||||
closeIcon={<i className="iconfont icon-guanbi font-35 closeIconFont"></i>}
|
||||
footer={<Button type="primary" style={{width: '385px', height: '42px'}} className="font-15">确认安装</Button>}
|
||||
footer={<Button type="primary" style={{width: '385px', height: '42px'}} className="font-15" onClick={okClick}>确认安装</Button>}
|
||||
>
|
||||
<div className="installTextBox">
|
||||
<div className="installTil font-18">安装位置</div>
|
||||
<Radio.Group onChange={(e)=>{setCheckValue(e.target.value)}} value={checkValue}>
|
||||
<Radio value={0} className="installRadioBox mt10 font-16">安装到所有仓库<br/><span className="font-15 installRadioBoxTip">安装到用户拥有的所有仓库中</span></Radio>
|
||||
<Radio value={1} className="installRadioBox mt15 font-16">安装到指定仓库<br/><span className="font-15 installRadioBoxTip">请至少选择一个仓库</span></Radio>
|
||||
<Radio value={1} className="installRadioBox mt15 font-16">安装到指定仓库<br/><span className={`font-15 installRadioBoxTip ${errTip ? 'errTip' :''}`}>请至少选择一个仓库</span></Radio>
|
||||
</Radio.Group>
|
||||
{checkValue === 1 && <Select
|
||||
placeholder="请输入仓库名称"
|
||||
value={selectValue}
|
||||
placeholder="请选择仓库"
|
||||
value={selectValue.map(item=>{return item.id})}
|
||||
onChange={selectChange}
|
||||
className="installSelectBox"
|
||||
dropdownClassName="installDropdownClass"
|
||||
optionLabelProp="label"
|
||||
>
|
||||
{filterOption.map(item=>(<Select.Option key={item} value={item}>{item}</Select.Option>))}
|
||||
{filterOption.map(item=>(<Select.Option key={item.id} value={item.id}>{item.name}</Select.Option>))}
|
||||
</Select>}
|
||||
{selectValue.map((item, index)=>{return <div key={index} className="selectValueBox font-14"><i className="iconfont icon-daimakuicon1 font-14 mr5"></i><span className="selectValue">{item}</span><i className="iconfont icon-guanbi font-12 close ml30" onClick={()=>{deleteSelect(item)}}></i></div>})}
|
||||
{checkValue === 1 && selectValue.map((item, index)=>{return <div key={index} className="selectValueBox font-14"><i className="iconfont icon-daimakuicon1 font-14 mr5"></i><span className="selectValue">{item.name}</span><i className="iconfont icon-guanbi font-12 close ml30" onClick={()=>{deleteSelect(item)}}></i></div>})}
|
||||
<div className="installTil font-18 mt20 mb10">权限信息</div>
|
||||
<div className="mb10"><Checkbox className="greenCol font-16">代码库只读权限</Checkbox></div>
|
||||
<div className="mb20"><Checkbox className="greenCol font-16">合并请求(PR)读写权限</Checkbox></div>
|
||||
{detail && <div className="mb10"><Checkbox className="greenCol font-16" checked={detail.limit_and_events.juris_diction_code !== 2}>代码库{detail.limit_and_events.juris_diction_code === 2 ? '无' : detail.limit_and_events.juris_diction_code === 1 ? '读写' : '只读'}权限</Checkbox></div>}
|
||||
{detail && <div className="mb20"><Checkbox className="greenCol font-16" checked={detail.limit_and_events.juris_diction_pr !== 2}>合并请求(PR){detail.limit_and_events.juris_diction_pr === 2 ? '无' : detail.limit_and_events.juris_diction_pr === 1 ? '读写' : '只读'}权限</Checkbox></div>}
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
.botImgBg{
|
||||
width: 86px;
|
||||
height: 86px;
|
||||
line-height: 86px;
|
||||
border-radius: 50%;
|
||||
background-color: yellowgreen;
|
||||
border: 1px solid white;
|
||||
img{
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
.centerBox{
|
||||
width: 77%;
|
||||
|
@ -59,6 +62,7 @@
|
|||
.installBotImgBox{
|
||||
width:100px;
|
||||
height:100px;
|
||||
line-height:100px;
|
||||
background-color:#e9f1ff;
|
||||
border:3px solid#ffffff;
|
||||
border-radius: 50%;
|
||||
|
@ -66,6 +70,9 @@
|
|||
top: -50px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
.installBotImg{
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
.installBotName{
|
||||
color:#151d40;
|
||||
|
@ -105,6 +112,9 @@
|
|||
display: inline-block;
|
||||
margin: 5px 0 0 23px;
|
||||
color:#99a2af;
|
||||
&.errTip{
|
||||
color:#f60011;
|
||||
}
|
||||
}
|
||||
.selectValueBox{
|
||||
margin: 13px 0 0px 23px;
|
||||
|
|
|
@ -1,25 +1,48 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Button, Input, Pagination } from "antd";
|
||||
import { Button, Input, Pagination, Spin } from "antd";
|
||||
import { getImageUrl } from 'educoder'
|
||||
import './index.scss';
|
||||
import { Link } from "react-router-dom";
|
||||
import {getAllBotCategory} from '../api.js';
|
||||
import {getAllBotCategory, getContentsLikeNameAndFunc} from '../api.js';
|
||||
import Nodata from '../../forge/Nodata'
|
||||
|
||||
function SoftBot(props){
|
||||
const {mygetHelmetapi} = props;
|
||||
const [current, setCurrent] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
const [pageSize, setPageSize] = useState(12);
|
||||
const [total, setTotal] = useState(500);
|
||||
const [activeKet, setActiveKey] = useState(-1);
|
||||
const [botList, setBotList] = useState([{name: 'hahahah', user: 'aaa908', intro: 'jfsdjhafasdjhg', degree:125, img: '', id: 1}, {name: 'hahahah', user: 'aaa908', intro: 'jfsdjhafasdjhg', degree:125, img: '', id: 2}, {name: 'hahahah', user: 'aaa908', intro: 'jfsdjhafasdjhg', degree:125, img: '', id: 3}, {name: 'hahahah', user: 'aaa908', intro: 'jfsdjhafasdjhg', degree:125, img: '', id: 4}, {name: 'hahahah', user: 'aaa908', intro: 'jfsdjhafasdjhg', degree:125, img: '', id: 5}, {name: 'hahahah', user: 'aaa908', intro: 'jfsdjhafasdjhg', degree:125, img: '', id: 6}])
|
||||
const [navList, setNavList] = useState([{key: '1', value: '接口管理'}, {key: '2', value: '代码审阅'}])
|
||||
const [keyWord, setKeyWord] = useState(undefined);
|
||||
const [botList, setBotList] = useState([])
|
||||
const [navList, setNavList] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
// 获取分类列表
|
||||
getAllBotCategory().then(res=>{
|
||||
console.log('res', res);
|
||||
if(res && res.code === 200){
|
||||
setNavList(res.data && res.data.category_list);
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(()=>{
|
||||
// 获取softbot列表
|
||||
setLoading(true);
|
||||
getContentsLikeNameAndFunc({
|
||||
func: activeKet === -1 ? "" : activeKet,
|
||||
name: keyWord || "",
|
||||
page_no: current,
|
||||
page_size: pageSize
|
||||
}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
setTotal(res.data && res.data.total);
|
||||
setBotList(res.data && res.data.bot_list);
|
||||
}
|
||||
setLoading(false);
|
||||
})
|
||||
}, [activeKet, keyWord, pageSize, current])
|
||||
|
||||
// 点击左侧类别导航栏
|
||||
function changeType(key){
|
||||
setActiveKey(key);
|
||||
|
@ -44,24 +67,26 @@ function SoftBot(props){
|
|||
<div className="botListBox">
|
||||
<div className="botListNav">
|
||||
<div className={`navItem font-16 ${activeKet === -1 ? 'active' : ''}`} onClick={()=>changeType(-1)}>全部分类</div>
|
||||
{navList.map(item=>{return <div className={`navItem font-16 ${activeKet === item.key ? 'active' : ''}`} key={item.key} onClick={()=>changeType(item.key)}>{item.value}</div>})}
|
||||
{navList.map((item, index)=>{return <div className={`navItem font-16 ${activeKet === item ? 'active' : ''}`} key={index} onClick={()=>changeType(item)}>{item}</div>})}
|
||||
</div>
|
||||
<div className="botListCont">
|
||||
<Input.Search enterButton={<i className="iconfont icon-sousuo_icon"></i>} placeholder="请输入关键字搜索bot" className="botListSearch"/>
|
||||
<Input.Search enterButton={<i className="iconfont icon-sousuo_icon"></i>} placeholder="请输入关键字搜索bot" className="botListSearch" onSearch={(value)=>{setKeyWord(value)}} allowClear style={{marginLeft: '33px', width: '96.5%'}}/>
|
||||
<div className="botList">
|
||||
{botList.map((item, index)=>{
|
||||
return <div className="oneBotItem mt30" key={index} onClick={()=>{window.location.href=`/softbot/${item.id}`}}>
|
||||
{!loading && botList && botList.length > 0 && botList.map((item, index)=>{
|
||||
return <div className="oneBotItem mt30" key={index} onClick={()=>{window.location.href=`/softbot/${item.bot_id}`}}>
|
||||
<div className="oneItemHead">
|
||||
<div className="oneBotImgBox"><img src={item.img} alt="" className="oneBotImg"/></div>
|
||||
<div>
|
||||
<p className="font-16 oneBotName">{item.name}</p>
|
||||
<div className="oneBotImgBox"><img src={getImageUrl(item.logo)} alt="" className="oneBotImg"/></div>
|
||||
<div className="oneBotLine">
|
||||
<p className="font-16 oneBotName oneBotLine">{item.market_name}</p>
|
||||
<p>{item.user}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="botIntro">{item.intro}</div>
|
||||
<div className="degreeBox font-16">{item.degree}<span> 次</span></div>
|
||||
<div className="botIntro">{item.market_desc}</div>
|
||||
<div className="degreeBox font-16"><i className="iconfont icon-a-zu1404 mr5 font-16"></i>{item.install_num || 0}<span> 次</span></div>
|
||||
</div>
|
||||
})}
|
||||
{!loading && botList && !botList.length && <Nodata _html="暂无数据"/>}
|
||||
{loading && <Spin size="large" className="botLoading"/>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
}
|
||||
.botListCont{
|
||||
width: 100%;
|
||||
padding: 30px 22px 80px 40px;
|
||||
padding: 30px 22px 80px 0px;
|
||||
background-image:linear-gradient(180deg,#f3f5f8 0%,#ffffff 100%);
|
||||
box-shadow:8px 6px 18px rgba(171, 202, 255, 0.24) inset;
|
||||
.botListSearch{
|
||||
|
@ -81,11 +81,12 @@
|
|||
}
|
||||
.oneBotItem{
|
||||
cursor: pointer;
|
||||
width: 30%;
|
||||
width: 297px;
|
||||
background-color:#f4f5f8;
|
||||
border:1px solid #ffffff;
|
||||
border-radius:2px;
|
||||
box-shadow:0px 0px 12px rgba(82, 101, 223, 0.09);
|
||||
margin-left: 33px;
|
||||
.oneItemHead{
|
||||
align-items: center;
|
||||
background-image: url('../image/botOneBg.png');
|
||||
|
@ -97,26 +98,51 @@
|
|||
.oneBotImgBox{
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
border-radius: 50%;
|
||||
background-color: yellow;
|
||||
border:1px solid #ffffff;
|
||||
margin-right: 15px;
|
||||
img{
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.botIntro{
|
||||
padding: 14px 17px 10px 14px;
|
||||
margin: 14px 17px 10px 14px;
|
||||
color:#8893af;
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.degreeBox{
|
||||
color:#151d40;
|
||||
padding: 0 0 12px 12px;
|
||||
&>.icon-a-zu1404{
|
||||
color: #4c5b76;
|
||||
}
|
||||
}
|
||||
}
|
||||
.botList{
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-start;
|
||||
&>.none_panels{
|
||||
margin: 0 auto;
|
||||
}
|
||||
.botLoading{
|
||||
margin: 200px auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
.botListPagination{
|
||||
text-align: right;
|
||||
}
|
||||
.oneBotLine{
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex: 0.8;
|
||||
}
|
Loading…
Reference in New Issue