feat: 项目setting成员设置

This commit is contained in:
wenbo.dong 2017-08-18 17:08:37 +08:00
parent 53154d244a
commit 2f979a0e98
9 changed files with 292 additions and 71 deletions

View File

@ -1,8 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Table } from 'antd';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Select, Button, Modal, Row, Col, message, Popconfirm } from 'antd'; import { Table, Select, Button, Modal, Row, Col, message, Popconfirm } from 'antd';
import './MemberList.scss'; import './MemberList.scss';
import { autobind } from 'core-decorators'; import { autobind } from 'core-decorators';
import { fetchGroupMemberList, fetchGroupMsg, addMember, delMember, changeMemberRole } from '../../../reducer/modules/group.js' import { fetchGroupMemberList, fetchGroupMsg, addMember, delMember, changeMemberRole } from '../../../reducer/modules/group.js'

View File

@ -1,10 +1,24 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { Card, Badge } from 'antd'; import { Table, Card, Badge, Select, Button, Modal, Row, Col, message, Popconfirm } from 'antd';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { autobind } from 'core-decorators';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { fetchGroupMemberList } from '../../../../reducer/modules/group.js'; import { fetchGroupMemberList } from '../../../../reducer/modules/group.js';
import { getProjectMsg, getProjectMemberList, addMember, delMember, changeMemberRole } from '../../../../reducer/modules/project.js';
import UsernameAutoComplete from '../../../../components/UsernameAutoComplete/UsernameAutoComplete.js';
import '../Setting.scss'; import '../Setting.scss';
const Option = Select.Option;
const arrayAddKey = (arr) => {
return arr.map((item, index) => {
return {
...item,
key: index
}
});
}
@connect( @connect(
state => { state => {
return { return {
@ -13,7 +27,12 @@ import '../Setting.scss';
} }
}, },
{ {
fetchGroupMemberList fetchGroupMemberList,
getProjectMsg,
getProjectMemberList,
addMember,
delMember,
changeMemberRole
} }
) )
class ProjectMember extends Component { class ProjectMember extends Component {
@ -21,31 +40,186 @@ class ProjectMember extends Component {
super(props); super(props);
this.state = { this.state = {
groupMemberList: [], groupMemberList: [],
groupName: '' projectMemberList: [],
groupName: '',
role: '',
visible: false,
dataSource: [],
inputUid: 0,
inputRole: 'dev'
} }
} }
static propTypes = { static propTypes = {
projectId: PropTypes.number,
projectMsg: PropTypes.object, projectMsg: PropTypes.object,
uid: PropTypes.number, uid: PropTypes.number,
fetchGroupMemberList: PropTypes.func addMember: PropTypes.func,
delMember: PropTypes.func,
changeMemberRole: PropTypes.func,
fetchGroupMemberList: PropTypes.func,
getProjectMsg: PropTypes.func,
getProjectMemberList: PropTypes.func
} }
@autobind
showAddMemberModal() {
this.setState({
visible: true
});
}
// 重新获取列表
@autobind
reFetchList() {
this.props.getProjectMemberList(this.props.projectId).then((res) => {
this.setState({
projectMemberList: arrayAddKey(res.payload.data.data),
visible: false
});
});
}
// 增 - 添加成员
@autobind
handleOk() {
console.log(this.props.projectId, this.state.inputUid);
this.props.addMember({
id: this.props.projectId,
member_uid: this.state.inputUid
}).then((res) => {
console.log(res);
if (!res.payload.data.errcode) {
message.success('添加成功!');
this.reFetchList(); // 添加成功后重新获取分组成员列表
}
});
}
// 添加成员时 选择新增成员权限
@autobind
changeNewMemberRole(value) {
return () => {
console.log(this.props.projectId, value);
}
}
// 删 - 删除分组成员
@autobind
deleteConfirm(member_uid) {
return () => {
const id = this.props.projectId;
this.props.delMember({ id, member_uid }).then((res) => {
if (!res.payload.data.errcode) {
message.success(res.payload.data.errmsg);
this.reFetchList(); // 添加成功后重新获取分组成员列表
}
});
}
}
// 改 - 修改成员权限
@autobind
changeUserRole(e) {
console.log(e);
const id = this.props.projectId;
const role = e.split('-')[0];
const member_uid = e.split('-')[1];
this.props.changeMemberRole({ id, member_uid, role }).then((res) => {
if (!res.payload.data.errcode) {
message.success(res.payload.data.errmsg);
this.reFetchList(); // 添加成功后重新获取分组成员列表
}
});
}
// 关闭模态框
@autobind
handleCancel() {
this.setState({
visible: false
});
}
@autobind
onUserSelect(childState) {
console.log(childState);
this.setState({
inputUid: childState.uid
})
}
async componentWillMount() { async componentWillMount() {
const groupMemberList = await this.props.fetchGroupMemberList(this.props.projectMsg.group_id); const groupMemberList = await this.props.fetchGroupMemberList(this.props.projectMsg.group_id);
console.log(groupMemberList); const rojectMsg = await this.props.getProjectMsg(this.props.projectId);
const projectMemberList = await this.props.getProjectMemberList(this.props.projectId);
this.setState({ this.setState({
groupMemberList: groupMemberList.payload.data.data, groupMemberList: groupMemberList.payload.data.data,
groupName: this.props.projectMsg.group_name groupName: this.props.projectMsg.group_name,
projectMemberList: arrayAddKey(projectMemberList.payload.data.data),
role: rojectMsg.payload.data.data.role
}) })
} }
render () { render () {
console.log(this.props); console.log(this.props);
console.log(this.state);
const columns = [{
title: ' 项目成员 ('+this.state.projectMemberList.length + ') 人',
dataIndex: 'username',
key: 'username',
render: (text, record) => {
return (<div className="m-user">
<img src={location.protocol + '//' + location.host + '/api/user/avatar?uid=' + record.uid} className="m-user-img" />
<p className="m-user-name">{text}</p>
</div>);
}
}, {
title: (this.state.role === 'owner' || this.state.role === 'admin') ? <div className="btn-container"><Button className="btn" type="primary" icon="plus" onClick={this.showAddMemberModal}>添加成员</Button></div> : '',
key: 'action',
className: 'member-opration',
render: (text, record) => {
if (this.state.role === 'owner' || this.state.role === 'admin') {
return (
<div>
<Select defaultValue={record.role+'-'+record.uid} className="select" onChange={this.changeUserRole}>
<Option value={'owner-'+record.uid}>组长</Option>
<Option value={'dev-'+record.uid}>开发者</Option>
</Select>
<Popconfirm placement="topRight" title="你确定要删除吗? " onConfirm={this.deleteConfirm(record.uid)} okText="确定" cancelText="">
<Button type="danger" icon="minus" className="btn-danger" />
</Popconfirm>
</div>
)
} else {
return '';
}
}
}];
return ( return (
<div className="m-panel"> <div className="m-panel">
<Card title={this.state.groupName + ' 分组成员 ' + '(' + this.state.groupMemberList.length + ')'} noHovering className="setting-group"> <Modal
title="添加成员"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
>
<Row gutter={6} className="modal-input">
<Col span="5"><div className="label">用户名: </div></Col>
<Col span="15">
<UsernameAutoComplete callbackState={this.onUserSelect} />
</Col>
</Row>
<Row gutter={6} className="modal-input">
<Col span="5"><div className="label">权限: </div></Col>
<Col span="15">
<Select size="large" defaultValue="dev" className="select" onChange={this.changeNewMemberRole}>
<Option value="owner">组长</Option>
<Option value="dev">开发者</Option>
</Select>
</Col>
</Row>
</Modal>
<Table columns={columns} dataSource={this.state.projectMemberList} pagination={false} />
<Card title={this.state.groupName + ' 分组成员 ' + '(' + this.state.groupMemberList.length + ') 人'} noHovering className="setting-group">
{this.state.groupMemberList.map((item, index) => { {this.state.groupMemberList.map((item, index) => {
console.log(this.props.uid);
console.log(item);
return (<div key={index} className="card-item"> return (<div key={index} className="card-item">
<img src={location.protocol + '//' + location.host + '/api/user/avatar?uid=' + item.uid} className="item-img" /> <img src={location.protocol + '//' + location.host + '/api/user/avatar?uid=' + item.uid} className="item-img" />
<p className="item-name">{item.username}</p> <p className="item-name">{item.username}</p>

View File

@ -9,6 +9,10 @@ const PROJECT_DEL = 'yapi/project/PROJECT_DEL';
// const CHANGE_TABLE_LOADING = 'yapi/project/CHANGE_TABLE_LOADING'; // const CHANGE_TABLE_LOADING = 'yapi/project/CHANGE_TABLE_LOADING';
const PROJECT_UPDATE = 'yapi/project/PROJECT_UPDATE'; const PROJECT_UPDATE = 'yapi/project/PROJECT_UPDATE';
const GET_CURR_PROJECT = 'yapi/project/GET_CURR_PROJECT' const GET_CURR_PROJECT = 'yapi/project/GET_CURR_PROJECT'
const GET_PEOJECT_MEMBER = 'yapi/project/GET_PEOJECT_MEMBER';
const ADD_PROJECT_MEMBER = 'yapi/project/ADD_PROJECT_MEMBER';
const DEL_PROJECT_MEMBER = 'yapi/project/DEL_PROJECT_MEMBER';
const CHANGE_PROJECT_MEMBER = 'yapi/project/CHANGE_PROJECT_MEMBER';
// Reducer // Reducer
const initialState = { const initialState = {
@ -93,6 +97,40 @@ export function getProjectMsg(id) {
}; };
} }
// 添加项目成员
export function addMember(param) {
return {
type: ADD_PROJECT_MEMBER,
payload: axios.post('/api/project/add_member', param)
}
}
// 删除项目成员
export function delMember(param) {
return {
type: DEL_PROJECT_MEMBER,
payload: axios.post('/api/project/del_member', param)
}
}
// 修改项目成员权限
export function changeMemberRole(param) {
return {
type: CHANGE_PROJECT_MEMBER,
payload: axios.post('/api/project/change_member_role', param)
}
}
// 获取项目成员列表
export function getProjectMemberList(id) {
return {
type: GET_PEOJECT_MEMBER,
payload: axios.get('/api/project/get_member_list', {
params: { id }
})
}
}
// export function changeTableLoading(data) { // export function changeTableLoading(data) {
// return { // return {
// type: CHANGE_TABLE_LOADING, // type: CHANGE_TABLE_LOADING,

View File

@ -375,25 +375,26 @@ class projectController extends baseController {
async changeMemberRole(ctx){ async changeMemberRole(ctx){
let params = ctx.request.body; let params = ctx.request.body;
let groupInst = yapi.getInst(groupModel); console.log(params);
let projectInst = yapi.getInst(projectModel);
if (!params.member_uid) { if (!params.member_uid) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组成员uid不能为空'); return ctx.body = yapi.commons.resReturn(null, 400, '项目成员uid不能为空');
} }
if (!params.id) { if (!params.id) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组id不能为空'); return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
} }
var check = await groupInst.checkMemberRepeat(params.id, params.member_uid); var check = await projectInst.checkMemberRepeat(params.id, params.member_uid);
if (check === 0) { if (check === 0) {
return ctx.body = yapi.commons.resReturn(null, 400, '分组成员不存在'); return ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在');
} }
if (await this.checkAuth(id, 'group', 'danger') !== true) { if (await this.checkAuth(params.id, 'group', 'danger') !== true) {
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限'); return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
} }
params.role = params.role === 'owner' ? 'owner' : 'dev'; params.role = params.role === 'owner' ? 'owner' : 'dev';
try { try {
let result = await groupInst.changeMemberRole(params.id, params.member_uid, params.role); let result = await projectInst.changeMemberRole(params.id, params.member_uid, params.role);
let username = this.getUsername(); let username = this.getUsername();
let project = await this.Model.get(params.id); let project = await this.Model.get(params.id);

View File

@ -141,7 +141,7 @@ class projectModel extends baseModel {
_id: id, _id: id,
"members.uid": uid "members.uid": uid
}, { }, {
"$set": { "members.$.uid": role} "$set": { "members.$.role": role}
} }
); );
} }

View File

@ -203,6 +203,11 @@ const routerConfig = {
"path": "del_member", "path": "del_member",
"method": "post" "method": "post"
}, },
{
"action": "changeMemberRole",
"path": "change_member_role",
"method": "post"
},
{ {
"action": "getMemberList", "action": "getMemberList",
"path": "get_member_list", "path": "get_member_list",
@ -213,7 +218,7 @@ const routerConfig = {
"path": "search", "path": "search",
"method": "get" "method": "get"
}, },
{ {
"action": "download", "action": "download",
"path": "download", "path": "download",
"method": "get" "method": "get"

View File

@ -792,16 +792,15 @@ var projectController = function (_baseController) {
key: 'del', key: 'del',
value: function () { value: function () {
var _ref8 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee8(ctx) { var _ref8 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee8(ctx) {
var _id, interfaceInst, interfaceColInst, interfaceCaseInst, result; var id, interfaceInst, interfaceColInst, interfaceCaseInst, result;
return _regenerator2.default.wrap(function _callee8$(_context8) { return _regenerator2.default.wrap(function _callee8$(_context8) {
while (1) { while (1) {
switch (_context8.prev = _context8.next) { switch (_context8.prev = _context8.next) {
case 0: case 0:
_context8.prev = 0; _context8.prev = 0;
_id = ctx.request.body.id; id = ctx.request.body.id;
if (_id) { if (id) {
_context8.next = 4; _context8.next = 4;
break; break;
} }
@ -810,7 +809,7 @@ var projectController = function (_baseController) {
case 4: case 4:
_context8.next = 6; _context8.next = 6;
return this.checkAuth(_id, 'project', 'danger'); return this.checkAuth(id, 'project', 'danger');
case 6: case 6:
_context8.t0 = _context8.sent; _context8.t0 = _context8.sent;
@ -827,19 +826,19 @@ var projectController = function (_baseController) {
interfaceColInst = _yapi2.default.getInst(_interfaceCol2.default); interfaceColInst = _yapi2.default.getInst(_interfaceCol2.default);
interfaceCaseInst = _yapi2.default.getInst(_interfaceCase2.default); interfaceCaseInst = _yapi2.default.getInst(_interfaceCase2.default);
_context8.next = 14; _context8.next = 14;
return interfaceInst.delByProjectId(_id); return interfaceInst.delByProjectId(id);
case 14: case 14:
_context8.next = 16; _context8.next = 16;
return interfaceCaseInst.delByProjectId(_id); return interfaceCaseInst.delByProjectId(id);
case 16: case 16:
_context8.next = 18; _context8.next = 18;
return interfaceColInst.delByProjectId(_id); return interfaceColInst.delByProjectId(id);
case 18: case 18:
_context8.next = 20; _context8.next = 20;
return this.Model.del(_id); return this.Model.del(id);
case 20: case 20:
result = _context8.sent; result = _context8.sent;
@ -872,77 +871,79 @@ var projectController = function (_baseController) {
key: 'changeMemberRole', key: 'changeMemberRole',
value: function () { value: function () {
var _ref9 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee9(ctx) { var _ref9 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee9(ctx) {
var params, groupInst, check, result, username, project, member; var params, projectInst, check, result, username, project, member;
return _regenerator2.default.wrap(function _callee9$(_context9) { return _regenerator2.default.wrap(function _callee9$(_context9) {
while (1) { while (1) {
switch (_context9.prev = _context9.next) { switch (_context9.prev = _context9.next) {
case 0: case 0:
params = ctx.request.body; params = ctx.request.body;
groupInst = _yapi2.default.getInst(_group2.default);
console.log(params);
projectInst = _yapi2.default.getInst(_project2.default);
if (params.member_uid) { if (params.member_uid) {
_context9.next = 4; _context9.next = 5;
break; break;
} }
return _context9.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '分组成员uid不能为空')); return _context9.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目成员uid不能为空'));
case 4: case 5:
if (params.id) { if (params.id) {
_context9.next = 6; _context9.next = 7;
break; break;
} }
return _context9.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '分组id不能为空')); return _context9.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目id不能为空'));
case 6: case 7:
_context9.next = 8; _context9.next = 9;
return groupInst.checkMemberRepeat(params.id, params.member_uid); return projectInst.checkMemberRepeat(params.id, params.member_uid);
case 8: case 9:
check = _context9.sent; check = _context9.sent;
if (!(check === 0)) { if (!(check === 0)) {
_context9.next = 11; _context9.next = 12;
break; break;
} }
return _context9.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '分组成员不存在')); return _context9.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '项目成员不存在'));
case 11: case 12:
_context9.next = 13; _context9.next = 14;
return this.checkAuth(id, 'group', 'danger'); return this.checkAuth(params.id, 'group', 'danger');
case 13: case 14:
_context9.t0 = _context9.sent; _context9.t0 = _context9.sent;
if (!(_context9.t0 !== true)) { if (!(_context9.t0 !== true)) {
_context9.next = 16; _context9.next = 17;
break; break;
} }
return _context9.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 405, '没有权限')); return _context9.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 405, '没有权限'));
case 16: case 17:
params.role = params.role === 'owner' ? 'owner' : 'dev'; params.role = params.role === 'owner' ? 'owner' : 'dev';
_context9.prev = 17; _context9.prev = 18;
_context9.next = 20; _context9.next = 21;
return groupInst.changeMemberRole(params.id, params.member_uid, params.role); return projectInst.changeMemberRole(params.id, params.member_uid, params.role);
case 20: case 21:
result = _context9.sent; result = _context9.sent;
username = this.getUsername(); username = this.getUsername();
_context9.next = 24; _context9.next = 25;
return this.Model.get(params.id); return this.Model.get(params.id);
case 24: case 25:
project = _context9.sent; project = _context9.sent;
_context9.next = 27; _context9.next = 28;
return _yapi2.default.getInst(_user2.default).findByUids(params.member_uid); return _yapi2.default.getInst(_user2.default).findByUids(params.member_uid);
case 27: case 28:
member = _context9.sent; member = _context9.sent;
_yapi2.default.commons.saveLog({ _yapi2.default.commons.saveLog({
@ -955,21 +956,21 @@ var projectController = function (_baseController) {
icon: project.icon icon: project.icon
}); });
ctx.body = _yapi2.default.commons.resReturn(result); ctx.body = _yapi2.default.commons.resReturn(result);
_context9.next = 35; _context9.next = 36;
break; break;
case 32: case 33:
_context9.prev = 32; _context9.prev = 33;
_context9.t1 = _context9['catch'](17); _context9.t1 = _context9['catch'](18);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context9.t1.message); ctx.body = _yapi2.default.commons.resReturn(null, 402, _context9.t1.message);
case 35: case 36:
case 'end': case 'end':
return _context9.stop(); return _context9.stop();
} }
} }
}, _callee9, this, [[17, 32]]); }, _callee9, this, [[18, 33]]);
})); }));
function changeMemberRole(_x10) { function changeMemberRole(_x10) {
@ -1000,14 +1001,13 @@ var projectController = function (_baseController) {
key: 'up', key: 'up',
value: function () { value: function () {
var _ref10 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee10(ctx) { var _ref10 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee10(ctx) {
var _id2, params, projectData, checkRepeat, data, result, username; var id, params, projectData, checkRepeat, data, result, username;
return _regenerator2.default.wrap(function _callee10$(_context10) { return _regenerator2.default.wrap(function _callee10$(_context10) {
while (1) { while (1) {
switch (_context10.prev = _context10.next) { switch (_context10.prev = _context10.next) {
case 0: case 0:
_context10.prev = 0; _context10.prev = 0;
_id2 = ctx.request.body.id; id = ctx.request.body.id;
params = ctx.request.body; params = ctx.request.body;
params.basepath = params.basepath || ''; params.basepath = params.basepath || '';
@ -1020,7 +1020,7 @@ var projectController = function (_baseController) {
color: 'string' color: 'string'
}); });
if (_id2) { if (id) {
_context10.next = 7; _context10.next = 7;
break; break;
} }
@ -1029,7 +1029,7 @@ var projectController = function (_baseController) {
case 7: case 7:
_context10.next = 9; _context10.next = 9;
return this.checkAuth(_id2, 'project', 'edit'); return this.checkAuth(id, 'project', 'edit');
case 9: case 9:
_context10.t0 = _context10.sent; _context10.t0 = _context10.sent;
@ -1043,7 +1043,7 @@ var projectController = function (_baseController) {
case 12: case 12:
_context10.next = 14; _context10.next = 14;
return this.Model.get(_id2); return this.Model.get(id);
case 14: case 14:
projectData = _context10.sent; projectData = _context10.sent;
@ -1094,7 +1094,7 @@ var projectController = function (_baseController) {
if (params.color) data.color = params.color; if (params.color) data.color = params.color;
if (params.icon) data.icon = params.icon; if (params.icon) data.icon = params.icon;
_context10.next = 33; _context10.next = 33;
return this.Model.up(_id2, data); return this.Model.up(id, data);
case 33: case 33:
result = _context10.sent; result = _context10.sent;
@ -1105,7 +1105,7 @@ var projectController = function (_baseController) {
type: 'project', type: 'project',
uid: this.getUid(), uid: this.getUid(),
username: username, username: username,
typeid: _id2, typeid: id,
icon: params.icon, icon: params.icon,
color: params.color color: params.color
}); });

View File

@ -187,7 +187,7 @@ var projectModel = function (_baseModel) {
_id: id, _id: id,
"members.uid": uid "members.uid": uid
}, { }, {
"$set": { "members.$.uid": role } "$set": { "members.$.role": role }
}); });
} }
}, { }, {

View File

@ -210,6 +210,10 @@ var routerConfig = {
"action": "delMember", "action": "delMember",
"path": "del_member", "path": "del_member",
"method": "post" "method": "post"
}, {
"action": "changeMemberRole",
"path": "change_member_role",
"method": "post"
}, { }, {
"action": "getMemberList", "action": "getMemberList",
"path": "get_member_list", "path": "get_member_list",