mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-07 01:41:39 +00:00
Import work weixin dep (#3803)
* dropdown import work weixin department * API import work weixin department * admin check group name conflict * work weixin department batch import * work weixin department import update return msg * work weixin department import not support batch * react work weixin department import * add IsProVersion work weixin department import * change style * check group name conflict
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
|
||||
import Loading from '../loading';
|
||||
|
||||
const propTypes = {
|
||||
importDepartmentDialogToggle: PropTypes.func.isRequired,
|
||||
onImportDepartmentSubmit: PropTypes.func.isRequired,
|
||||
departmentsCount: PropTypes.number.isRequired,
|
||||
membersCount: PropTypes.number.isRequired,
|
||||
departmentName: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
class ImportWorkWeixinDepartmentDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isLoading : false,
|
||||
};
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
this.props.importDepartmentDialogToggle(null);
|
||||
};
|
||||
|
||||
handleSubmit = () => {
|
||||
this.props.onImportDepartmentSubmit();
|
||||
this.setState({ isLoading : true });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { departmentsCount, membersCount, departmentName } = this.props;
|
||||
return (
|
||||
<Modal isOpen={true} toggle={this.toggle}>
|
||||
<ModalHeader toggle={this.toggle}>
|
||||
<span>{'导入部门 '}</span><span className="op-target" title={departmentName}>{departmentName}</span>
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<p>{'将要导入 '}<strong>{departmentsCount}</strong>{' 个部门,其中包括 '}<strong>{membersCount}</strong>{' 个成员'}</p>
|
||||
{this.state.isLoading && <Loading/>}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="secondary" onClick={this.toggle}>{'取消'}</Button>
|
||||
<Button color="primary" onClick={this.handleSubmit}>{'导入'}</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ImportWorkWeixinDepartmentDialog.propTypes = propTypes;
|
||||
|
||||
export default ImportWorkWeixinDepartmentDialog;
|
@@ -23,8 +23,9 @@
|
||||
height: 140px;
|
||||
}
|
||||
.dir-content-nav {
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
width: 24%;
|
||||
}
|
||||
.dir-content-nav:hover {
|
||||
overflow: auto;
|
||||
@@ -42,6 +43,8 @@
|
||||
}
|
||||
.tree-node-inner {
|
||||
position: relative;
|
||||
display: flex;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.tree-node-inner i {
|
||||
position: absolute;
|
||||
|
@@ -2,10 +2,12 @@ import React, { Component, Fragment } from 'react';
|
||||
import { Button } from 'reactstrap';
|
||||
import _ from 'lodash';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { gettext, siteRoot } from '../../utils/constants';
|
||||
import { gettext, siteRoot, isPro } from '../../utils/constants';
|
||||
import toaster from '../../components/toast';
|
||||
import Account from '../../components/common/account';
|
||||
import { WorkWeixinDepartmentMembersList, WorkWeixinDepartmentsTreePanel } from './work-weixin';
|
||||
import ImportWorkWeixinDepartmentDialog from '../../components/dialog/import-work-weixin-department-dialog';
|
||||
|
||||
import '../../css/work-weixin-departments.css';
|
||||
|
||||
class WorkWeixinDepartments extends Component {
|
||||
@@ -22,6 +24,10 @@ class WorkWeixinDepartments extends Component {
|
||||
newUsersTempObj: {},
|
||||
isCheckedAll: false,
|
||||
canCheckUserIds: [],
|
||||
isImportDepartmentDialogShow: false,
|
||||
importDepartment: null,
|
||||
importDepartmentChildrenCount: 0,
|
||||
importDepartmentMembersCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,13 +56,20 @@ class WorkWeixinDepartments extends Component {
|
||||
});
|
||||
};
|
||||
|
||||
getWorkWeixinDepartmentsList = () => {
|
||||
seafileAPI.adminListWorkWeixinDepartments().then((res) => {
|
||||
getWorkWeixinDepartmentsList = (departmentID) => {
|
||||
seafileAPI.adminListWorkWeixinDepartments(departmentID).then((res) => {
|
||||
if (!departmentID) {
|
||||
let departmentsTree = this.getDepartmentsTree(res.data.department);
|
||||
this.setState({
|
||||
isTreeLoading: false,
|
||||
departmentsTree: departmentsTree,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
importDepartmentChildrenCount: res.data.department.length,
|
||||
importDepartmentMembersCount: this.state.membersTempObj[departmentID].length,
|
||||
});
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.handleError(error);
|
||||
this.setState({
|
||||
@@ -213,6 +226,59 @@ class WorkWeixinDepartments extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
importDepartmentDialogToggle = (importDepartment) => {
|
||||
this.setState({
|
||||
isImportDepartmentDialogShow: !this.state.isImportDepartmentDialogShow,
|
||||
importDepartment: importDepartment,
|
||||
}, () => {
|
||||
if (importDepartment) {
|
||||
this.getWorkWeixinDepartmentsList(importDepartment.id);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onImportDepartmentSubmit = () => {
|
||||
let importDepartment = this.state.importDepartment;
|
||||
if (!importDepartment) return;
|
||||
seafileAPI.adminImportWorkWeixinDepartment(importDepartment.id).then((res) => {
|
||||
this.setState({
|
||||
isMembersListLoading: true,
|
||||
checkedDepartmentId: importDepartment.id,
|
||||
membersTempObj: {},
|
||||
membersList: [],
|
||||
newUsersTempObj: {},
|
||||
isCheckedAll: false,
|
||||
canCheckUserIds: [],
|
||||
});
|
||||
this.getWorkWeixinDepartmentMembersList(importDepartment.id);
|
||||
this.importDepartmentDialogToggle(null);
|
||||
if (res.data.success) {
|
||||
this.handleImportDepartmentSubmitSuccess(res.data.success);
|
||||
}
|
||||
if (res.data.failed) {
|
||||
this.handleImportDepartmentSubmitFailed(res.data.failed);
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.handleError(error);
|
||||
});
|
||||
};
|
||||
|
||||
handleImportDepartmentSubmitSuccess = (successes) => {
|
||||
for (let i = 0, len = successes.length; i < len; i++) {
|
||||
let success = successes[i];
|
||||
let successMsg = success.type === 'department' ? '部门 ' + success.department_name + ' 导入成功' : success.api_user_name + ' 导入成功' ;
|
||||
toaster.success(successMsg, { duration: 3 });
|
||||
}
|
||||
};
|
||||
|
||||
handleImportDepartmentSubmitFailed = (fails) => {
|
||||
for (let i = 0, len = fails.length; i < len; i++) {
|
||||
let fail = fails[i];
|
||||
let failName = fail.type === 'department' ? fail.department_name : fail.api_user_name;
|
||||
toaster.danger(failName + ' ' + fail.msg, { duration: 3} );
|
||||
}
|
||||
};
|
||||
|
||||
handleError = (e) => {
|
||||
if (e.response) {
|
||||
toaster.danger(e.response.data.error_msg || e.response.data.detail || gettext('Error'), {duration: 3});
|
||||
@@ -222,7 +288,7 @@ class WorkWeixinDepartments extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getWorkWeixinDepartmentsList();
|
||||
this.getWorkWeixinDepartmentsList(null);
|
||||
}
|
||||
|
||||
renderNav() {
|
||||
@@ -242,6 +308,8 @@ class WorkWeixinDepartments extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isImportDepartmentDialogShow, isTreeLoading, importDepartment, importDepartmentChildrenCount, importDepartmentMembersCount } = this.state;
|
||||
let canImportDepartment = !!(isPro && isImportDepartmentDialogShow && !isTreeLoading && importDepartment);
|
||||
return (
|
||||
<Fragment>
|
||||
{this.renderNav()}
|
||||
@@ -256,6 +324,7 @@ class WorkWeixinDepartments extends Component {
|
||||
isTreeLoading={this.state.isTreeLoading}
|
||||
onChangeDepartment={this.onChangeDepartment}
|
||||
checkedDepartmentId={this.state.checkedDepartmentId}
|
||||
importDepartmentDialogToggle={this.importDepartmentDialogToggle}
|
||||
/>
|
||||
<div className="dir-content-resize"></div>
|
||||
<WorkWeixinDepartmentMembersList
|
||||
@@ -271,6 +340,15 @@ class WorkWeixinDepartments extends Component {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{canImportDepartment &&
|
||||
<ImportWorkWeixinDepartmentDialog
|
||||
importDepartmentDialogToggle={this.importDepartmentDialogToggle}
|
||||
onImportDepartmentSubmit={this.onImportDepartmentSubmit}
|
||||
departmentsCount={importDepartmentChildrenCount}
|
||||
membersCount={importDepartmentMembersCount}
|
||||
departmentName={importDepartment.name}
|
||||
/>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
|
||||
import { gettext, isPro } from '../../../utils/constants';
|
||||
|
||||
const WorkWeixinDepartmentsTreeNodePropTypes = {
|
||||
index: PropTypes.number,
|
||||
@@ -8,6 +10,7 @@ const WorkWeixinDepartmentsTreeNodePropTypes = {
|
||||
isChildrenShow: PropTypes.bool.isRequired,
|
||||
onChangeDepartment: PropTypes.func.isRequired,
|
||||
checkedDepartmentId: PropTypes.number.isRequired,
|
||||
importDepartmentDialogToggle: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
class WorkWeixinDepartmentsTreeNode extends Component {
|
||||
@@ -16,6 +19,8 @@ class WorkWeixinDepartmentsTreeNode extends Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
isChildrenShow: false,
|
||||
dropdownOpen: false,
|
||||
active: false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,6 +32,18 @@ class WorkWeixinDepartmentsTreeNode extends Component {
|
||||
});
|
||||
};
|
||||
|
||||
dropdownToggle = () => {
|
||||
this.setState({ dropdownOpen: !this.state.dropdownOpen });
|
||||
};
|
||||
|
||||
onMouseEnter = () => {
|
||||
this.setState({ active: true });
|
||||
};
|
||||
|
||||
onMouseLeave = () => {
|
||||
this.setState({ active: false });
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.index === 0) {
|
||||
this.setState({ isChildrenShow: true });
|
||||
@@ -44,6 +61,7 @@ class WorkWeixinDepartmentsTreeNode extends Component {
|
||||
isChildrenShow={this.state.isChildrenShow}
|
||||
onChangeDepartment={this.props.onChangeDepartment}
|
||||
checkedDepartmentId={this.props.checkedDepartmentId}
|
||||
importDepartmentDialogToggle={this.props.importDepartmentDialogToggle}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@@ -63,9 +81,37 @@ class WorkWeixinDepartmentsTreeNode extends Component {
|
||||
return (
|
||||
<Fragment>
|
||||
{isChildrenShow &&
|
||||
<div className={nodeInnerClass} onClick={() => this.props.onChangeDepartment(department.id)}>
|
||||
<div
|
||||
className={nodeInnerClass}
|
||||
onClick={() => this.props.onChangeDepartment(department.id)}
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.onMouseLeave}
|
||||
>
|
||||
<i className={toggleClass} onClick={(e) => this.toggleChildren(e)}></i>{' '}
|
||||
<span className="tree-node-text">{department.name}</span>
|
||||
{isPro &&
|
||||
<Dropdown
|
||||
isOpen={this.state.dropdownOpen}
|
||||
toggle={this.dropdownToggle}
|
||||
direction="down"
|
||||
style={this.state.active ? {} : { opacity: 0 }}
|
||||
>
|
||||
<DropdownToggle
|
||||
tag='i'
|
||||
className='fa fa-ellipsis-v cursor-pointer attr-action-icon'
|
||||
title={gettext('More Operations')}
|
||||
data-toggle="dropdown"
|
||||
aria-expanded={this.state.dropdownOpen}
|
||||
>
|
||||
</DropdownToggle>
|
||||
<DropdownMenu className="drop-list" right={true}>
|
||||
<DropdownItem
|
||||
onClick={this.props.importDepartmentDialogToggle.bind(this, department)}
|
||||
id={department.id}
|
||||
>{'导入部门'}</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{this.state.isChildrenShow &&
|
||||
|
@@ -8,6 +8,7 @@ const WorkWeixinDepartmentsTreePanelPropTypes = {
|
||||
departmentsTree: PropTypes.array.isRequired,
|
||||
onChangeDepartment: PropTypes.func.isRequired,
|
||||
checkedDepartmentId: PropTypes.number.isRequired,
|
||||
importDepartmentDialogToggle: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
class WorkWeixinDepartmentsTreePanel extends Component {
|
||||
@@ -33,6 +34,7 @@ class WorkWeixinDepartmentsTreePanel extends Component {
|
||||
isChildrenShow={true}
|
||||
onChangeDepartment={this.props.onChangeDepartment}
|
||||
checkedDepartmentId={this.props.checkedDepartmentId}
|
||||
importDepartmentDialogToggle={this.props.importDepartmentDialogToggle}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@@ -5,6 +5,7 @@ import logging
|
||||
import requests
|
||||
import json
|
||||
|
||||
from seaserv import seafile_api, ccnet_api
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.response import Response
|
||||
@@ -13,6 +14,8 @@ from rest_framework import status
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.api2.utils import api_error
|
||||
from seahub.api2.permissions import IsProVersion
|
||||
|
||||
from seahub.work_weixin.utils import handler_work_weixin_api_response, \
|
||||
get_work_weixin_access_token, admin_work_weixin_departments_check, \
|
||||
update_work_weixin_user_info
|
||||
@@ -21,10 +24,13 @@ from seahub.work_weixin.settings import WORK_WEIXIN_DEPARTMENTS_URL, \
|
||||
from seahub.base.accounts import User
|
||||
from seahub.utils.auth import gen_user_virtual_id
|
||||
from seahub.auth.models import SocialAuthUser
|
||||
from seahub.group.utils import validate_group_name
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
WORK_WEIXIN_DEPARTMENT_FIELD = 'department'
|
||||
WORK_WEIXIN_DEPARTMENT_MEMBERS_FIELD = 'userlist'
|
||||
DEPARTMENT_OWNER = 'system admin'
|
||||
|
||||
|
||||
# # uid = corpid + '_' + userid
|
||||
# from social_django.models import UserSocialAuth
|
||||
@@ -149,7 +155,6 @@ def _handler_work_weixin_user_data(api_user, social_auth_queryset):
|
||||
|
||||
|
||||
def _import_user_from_work_weixin(email, api_user):
|
||||
|
||||
api_user['username'] = email
|
||||
uid = WORK_WEIXIN_UID_PREFIX + api_user.get('userid')
|
||||
try:
|
||||
@@ -204,3 +209,235 @@ class AdminWorkWeixinUsersBatch(APIView):
|
||||
failed.append(error_data)
|
||||
|
||||
return Response({'success': success, 'failed': failed})
|
||||
|
||||
|
||||
class AdminWorkWeixinDepartmentsImport(APIView):
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
permission_classes = (IsAdminUser,)
|
||||
|
||||
def _list_departments_from_work_weixin(self, access_token, department_id):
|
||||
data = {
|
||||
'access_token': access_token,
|
||||
'id': department_id,
|
||||
}
|
||||
api_response = requests.get(WORK_WEIXIN_DEPARTMENTS_URL, params=data)
|
||||
api_response_dic = handler_work_weixin_api_response(api_response)
|
||||
|
||||
if not api_response_dic:
|
||||
logger.error('can not get work weixin departments response')
|
||||
return None
|
||||
|
||||
if WORK_WEIXIN_DEPARTMENT_FIELD not in api_response_dic:
|
||||
logger.error(json.dumps(api_response_dic))
|
||||
logger.error('can not get department list in work weixin departments response')
|
||||
return None
|
||||
|
||||
return api_response_dic[WORK_WEIXIN_DEPARTMENT_FIELD]
|
||||
|
||||
def _list_department_members_from_work_weixin(self, access_token, department_id):
|
||||
data = {
|
||||
'access_token': access_token,
|
||||
'department_id': department_id,
|
||||
'fetch_child': 1,
|
||||
}
|
||||
api_response = requests.get(WORK_WEIXIN_DEPARTMENT_MEMBERS_URL, params=data)
|
||||
api_response_dic = handler_work_weixin_api_response(api_response)
|
||||
|
||||
if not api_response_dic:
|
||||
logger.error('can not get work weixin department members response')
|
||||
return None
|
||||
|
||||
if WORK_WEIXIN_DEPARTMENT_MEMBERS_FIELD not in api_response_dic:
|
||||
logger.error(json.dumps(api_response_dic))
|
||||
logger.error('can not get userlist in work weixin department members response')
|
||||
return None
|
||||
|
||||
return api_response_dic[WORK_WEIXIN_DEPARTMENT_MEMBERS_FIELD]
|
||||
|
||||
def _admin_check_group_name_conflict(self, new_group_name):
|
||||
checked_groups = ccnet_api.search_groups(new_group_name, -1, -1)
|
||||
|
||||
for g in checked_groups:
|
||||
if g.group_name == new_group_name:
|
||||
return True, g
|
||||
|
||||
return False, None
|
||||
|
||||
def _api_department_success_msg(self, department_obj_id, department_obj_name, group_id):
|
||||
return {
|
||||
'type': 'department',
|
||||
'department_id': department_obj_id,
|
||||
'department_name': department_obj_name,
|
||||
'group_id': group_id,
|
||||
}
|
||||
|
||||
def _api_department_failed_msg(self, department_obj_id, department_obj_name, msg):
|
||||
return {
|
||||
'type': 'department',
|
||||
'department_id': department_obj_id,
|
||||
'department_name': department_obj_name,
|
||||
'msg': msg,
|
||||
}
|
||||
|
||||
def _api_user_success_msg(self, email, api_user_name, department_obj_id, group_id):
|
||||
return {
|
||||
'type': 'user',
|
||||
'email': email,
|
||||
'api_user_name': api_user_name,
|
||||
'department_id': department_obj_id,
|
||||
'group_id': group_id,
|
||||
}
|
||||
|
||||
def _api_user_failed_msg(self, email, api_user_name, department_obj_id, msg):
|
||||
return {
|
||||
'type': 'user',
|
||||
'email': email,
|
||||
'api_user_name': api_user_name,
|
||||
'department_id': department_obj_id,
|
||||
'msg': msg,
|
||||
}
|
||||
|
||||
def post(self, request):
|
||||
"""import department from work weixin
|
||||
|
||||
permission: IsProVersion
|
||||
"""
|
||||
# argument check
|
||||
department_id = request.data.get('work_weixin_department_id')
|
||||
try:
|
||||
department_id = int(department_id)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
error_msg = 'work_weixin_department_ids invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
# is pro version and work weixin check
|
||||
if not IsProVersion or not admin_work_weixin_departments_check():
|
||||
error_msg = 'Feature is not enabled.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
access_token = get_work_weixin_access_token()
|
||||
if not access_token:
|
||||
logger.error('can not get work weixin access_token')
|
||||
error_msg = '获取企业微信组织架构失败'
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# list departments from work weixin
|
||||
api_department_list = self._list_departments_from_work_weixin(access_token, department_id)
|
||||
if api_department_list is None:
|
||||
error_msg = '获取企业微信组织架构失败'
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# list department members from work weixin
|
||||
api_user_list = self._list_department_members_from_work_weixin(access_token, department_id)
|
||||
if api_user_list is None:
|
||||
error_msg = '获取企业微信组织架构成员失败'
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# main
|
||||
success = list()
|
||||
failed = list()
|
||||
department_map_to_group_dict = dict()
|
||||
|
||||
for index, department_obj in enumerate(api_department_list):
|
||||
# check department argument
|
||||
new_group_name = department_obj.get('name')
|
||||
department_obj_id = department_obj.get('id')
|
||||
if department_obj_id is None or not new_group_name or not validate_group_name(new_group_name):
|
||||
failed_msg = self._api_department_failed_msg(
|
||||
department_obj_id, new_group_name, '部门参数错误')
|
||||
failed.append(failed_msg)
|
||||
continue
|
||||
|
||||
# check parent group
|
||||
if index == 0:
|
||||
parent_group_id = -1
|
||||
else:
|
||||
parent_department_id = department_obj.get('parentid')
|
||||
parent_group_id = department_map_to_group_dict.get(parent_department_id)
|
||||
|
||||
if parent_group_id is None:
|
||||
failed_msg = self._api_department_failed_msg(
|
||||
department_obj_id, new_group_name, '父级部门不存在')
|
||||
failed.append(failed_msg)
|
||||
continue
|
||||
|
||||
# check department exist by group name
|
||||
exist, exist_group = self._admin_check_group_name_conflict(new_group_name)
|
||||
if exist:
|
||||
department_map_to_group_dict[department_obj_id] = exist_group.id
|
||||
failed_msg = self._api_department_failed_msg(
|
||||
department_obj_id, new_group_name, '部门已存在')
|
||||
failed.append(failed_msg)
|
||||
continue
|
||||
|
||||
# import department
|
||||
try:
|
||||
group_id = ccnet_api.create_group(
|
||||
new_group_name, DEPARTMENT_OWNER, parent_group_id=parent_group_id)
|
||||
|
||||
seafile_api.set_group_quota(group_id, -2)
|
||||
|
||||
department_map_to_group_dict[department_obj_id] = group_id
|
||||
success_msg = self._api_department_success_msg(
|
||||
department_obj_id, new_group_name, group_id)
|
||||
success.append(success_msg)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
failed_msg = self._api_department_failed_msg(
|
||||
department_obj_id, new_group_name, '部门导入失败')
|
||||
failed.append(failed_msg)
|
||||
|
||||
# todo filter ccnet User database
|
||||
social_auth_queryset = SocialAuthUser.objects.filter(
|
||||
provider=WORK_WEIXIN_PROVIDER, uid__contains=WORK_WEIXIN_UID_PREFIX)
|
||||
|
||||
# import api_user
|
||||
for api_user in api_user_list:
|
||||
uid = WORK_WEIXIN_UID_PREFIX + api_user.get('userid', '')
|
||||
api_user['contact_email'] = api_user['email']
|
||||
api_user_name = api_user.get('name')
|
||||
|
||||
# determine the user exists
|
||||
if social_auth_queryset.filter(uid=uid).exists():
|
||||
email = social_auth_queryset.get(uid=uid).username
|
||||
else:
|
||||
# create user
|
||||
email = gen_user_virtual_id()
|
||||
create_user_success = _import_user_from_work_weixin(email, api_user)
|
||||
if not create_user_success:
|
||||
failed_msg = self._api_user_failed_msg(
|
||||
'', api_user_name, department_id, '导入用户失败')
|
||||
failed.append(failed_msg)
|
||||
continue
|
||||
|
||||
# bind user to department
|
||||
api_user_department_list = api_user.get('department')
|
||||
for department_obj_id in api_user_department_list:
|
||||
group_id = department_map_to_group_dict.get(department_obj_id)
|
||||
if group_id is None:
|
||||
# the api_user also exist in the brother department which not import
|
||||
continue
|
||||
|
||||
if ccnet_api.is_group_user(group_id, email):
|
||||
failed_msg = self._api_user_failed_msg(
|
||||
email, api_user_name, department_obj_id, '部门成员已存在')
|
||||
failed.append(failed_msg)
|
||||
continue
|
||||
|
||||
try:
|
||||
ccnet_api.group_add_member(group_id, DEPARTMENT_OWNER, email)
|
||||
success_msg = self._api_user_success_msg(
|
||||
email, api_user_name, department_obj_id, group_id)
|
||||
success.append(success_msg)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
failed_msg = self._api_user_failed_msg(
|
||||
email, api_user_name, department_id, '导入部门成员失败')
|
||||
failed.append(failed_msg)
|
||||
|
||||
return Response({
|
||||
'success': success,
|
||||
'failed': failed,
|
||||
})
|
||||
|
@@ -141,7 +141,7 @@ from seahub.api2.endpoints.admin.user_activities import UserActivitiesView
|
||||
from seahub.api2.endpoints.admin.file_scan_records import AdminFileScanRecords
|
||||
from seahub.api2.endpoints.admin.notifications import AdminNotificationsView
|
||||
from seahub.api2.endpoints.admin.work_weixin import AdminWorkWeixinDepartments, \
|
||||
AdminWorkWeixinDepartmentMembers, AdminWorkWeixinUsersBatch
|
||||
AdminWorkWeixinDepartmentMembers, AdminWorkWeixinUsersBatch, AdminWorkWeixinDepartmentsImport
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^accounts/', include('seahub.base.registration_urls')),
|
||||
@@ -549,6 +549,7 @@ urlpatterns = [
|
||||
url(r'^api/v2.1/admin/work-weixin/departments/$', AdminWorkWeixinDepartments.as_view(), name='api-v2.1-admin-work-weixin-departments'),
|
||||
url(r'^api/v2.1/admin/work-weixin/departments/(?P<department_id>\d+)/members/$', AdminWorkWeixinDepartmentMembers.as_view(), name='api-v2.1-admin-work-weixin-department-members'),
|
||||
url(r'^api/v2.1/admin/work-weixin/users/batch/$', AdminWorkWeixinUsersBatch.as_view(), name='api-v2.1-admin-work-weixin-users'),
|
||||
url(r'^api/v2.1/admin/work-weixin/departments/import/$', AdminWorkWeixinDepartmentsImport.as_view(), name='api-v2.1-admin-work-weixin-department-import'),
|
||||
|
||||
### system admin ###
|
||||
url(r'^sysadmin/$', sysadmin, name='sysadmin'),
|
||||
|
Reference in New Issue
Block a user