temp.
							parent
							
								
									39ced04d25
								
							
						
					
					
						commit
						1db8db69c6
					
				| 
						 | 
				
			
			@ -829,6 +829,7 @@ $app.create_dlg_edit_host = function () {
 | 
			
		|||
                dlg.dom.edit_router_port.val('' + dlg.field_router_port);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            dlg.field_router_ip = '';
 | 
			
		||||
            dlg.field_router_port = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -878,88 +879,6 @@ $app.create_dlg_edit_host = function () {
 | 
			
		|||
    return dlg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
$app.create_dlg_host_info = function () {
 | 
			
		||||
    var dlg = {};
 | 
			
		||||
    dlg.dom_id = 'dlg-user-info';
 | 
			
		||||
    dlg.row_id = -1;
 | 
			
		||||
    dlg.need_edit = false;
 | 
			
		||||
 | 
			
		||||
    dlg.dom = {
 | 
			
		||||
        dialog: $('#' + dlg.dom_id),
 | 
			
		||||
        dlg_title: $('#' + dlg.dom_id + ' [data-field="dlg-title"]'),
 | 
			
		||||
        info: $('#' + dlg.dom_id + ' [data-field="user-info"]'),
 | 
			
		||||
        btn_edit: $('#' + dlg.dom_id + ' [data-field="btn-edit"]')
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    dlg.init = function (cb_stack) {
 | 
			
		||||
        dlg.dom.dialog.on('hidden.bs.modal', function () {
 | 
			
		||||
            if (!dlg.need_edit)
 | 
			
		||||
                return;
 | 
			
		||||
            $app.dlg_edit_user.show_edit(dlg.row_id);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        dlg.dom.btn_edit.click(function () {
 | 
			
		||||
            dlg.need_edit = true;
 | 
			
		||||
            dlg.dom.dialog.modal('hide');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        cb_stack.exec();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    dlg.show = function (row_id) {
 | 
			
		||||
        dlg.row_id = row_id;
 | 
			
		||||
        dlg.need_edit = false;
 | 
			
		||||
 | 
			
		||||
        var _row_data = $app.table_host.get_row(dlg.row_id);
 | 
			
		||||
 | 
			
		||||
        // 表格加载时,是不会读取用户的 desc 字段的,因此可以判断此用户是否已经读取过详细信息了
 | 
			
		||||
        if (_.isUndefined(_row_data.desc)) {
 | 
			
		||||
            // 尚未读取,则向服务器要求获取此用户账号的完整信息
 | 
			
		||||
            $tp.ajax_post_json('/user/get-user/' + _row_data.id, {},
 | 
			
		||||
                function (ret) {
 | 
			
		||||
                    if (ret.code === TPE_OK) {
 | 
			
		||||
                        $app.table_host.update_row(dlg.row_id, ret.data);
 | 
			
		||||
                        dlg.show_info(ret.data);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        $tp.notify_error('无法获取用户详细信息:' + tp_error_msg(ret.code, ret.message));
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                function () {
 | 
			
		||||
                    $tp.notify_error('网络故障,无法获取用户详细信息!');
 | 
			
		||||
                }
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            dlg.show_info(_row_data);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    dlg.show_info = function (user) {
 | 
			
		||||
        // 更新对话框中显示的信息
 | 
			
		||||
        dlg.dom.dlg_title.html('<i class="fa fa-vcard-o fa-fw"></i> ' + user.surname);
 | 
			
		||||
 | 
			
		||||
        var info = [];
 | 
			
		||||
 | 
			
		||||
        var not_set = '<span class="label label-sm label-ignore">未设置</span>';
 | 
			
		||||
        var mobile = (user.mobile.length === 0) ? not_set : user.mobile;
 | 
			
		||||
        var qq = (user.qq.length === 0) ? not_set : user.qq;
 | 
			
		||||
        var wechat = (user.wechat.length === 0) ? not_set : user.wechat;
 | 
			
		||||
        var desc = (user.desc.length === 0) ? not_set : user.desc;
 | 
			
		||||
        info.push('<tr><td class="key">账号:</td><td class="value">' + user.username + '</td></tr>');
 | 
			
		||||
        info.push('<tr><td class="key">姓名:</td><td class="value">' + user.surname + '</td></tr>');
 | 
			
		||||
        info.push('<tr><td class="key">邮箱:</td><td class="value">' + user.email + '</td></tr>');
 | 
			
		||||
        info.push('<tr><td class="key">电话:</td><td class="value">' + mobile + '</td></tr>');
 | 
			
		||||
        info.push('<tr><td class="key">QQ:</td><td class="value">' + qq + '</td></tr>');
 | 
			
		||||
        info.push('<tr><td class="key">微信:</td><td class="value">' + wechat + '</td></tr>');
 | 
			
		||||
        info.push('<tr><td class="key">描述:</td><td class="value"><div style="max-height:80px;overflow:auto;">' + desc + '</div></td></tr>');
 | 
			
		||||
 | 
			
		||||
        dlg.dom.info.html($(info.join('')));
 | 
			
		||||
 | 
			
		||||
        dlg.dom.dialog.modal();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return dlg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
$app.create_dlg_accounts = function () {
 | 
			
		||||
    var dlg = {};
 | 
			
		||||
    dlg.dom_id = 'dlg-accounts';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -486,7 +486,7 @@ class AppConfig(BaseAppConfig):
 | 
			
		|||
 | 
			
		||||
        self.sys.login = tp_convert_to_attr_dict(_login)
 | 
			
		||||
        if not self.sys.login.is_exists('session_timeout'):
 | 
			
		||||
            self.sys.login.session_timeout = 30
 | 
			
		||||
            self.sys.login.session_timeout = 60  # 1 hour
 | 
			
		||||
        if not self.sys.login.is_exists('retry'):
 | 
			
		||||
            self.sys.login.retry = 0
 | 
			
		||||
        if not self.sys.login.is_exists('lock_timeout'):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import datetime
 | 
			
		|||
import threading
 | 
			
		||||
 | 
			
		||||
from app.base.logger import log
 | 
			
		||||
from app.base.configs import get_cfg
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SessionManager(threading.Thread):
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +63,8 @@ class SessionManager(threading.Thread):
 | 
			
		|||
        """
 | 
			
		||||
 | 
			
		||||
        if expire is None:
 | 
			
		||||
            expire = self.SESSION_EXPIRE
 | 
			
		||||
            # expire = self.SESSION_EXPIRE
 | 
			
		||||
            expire = get_cfg().sys.login.session_timeout * 60
 | 
			
		||||
 | 
			
		||||
        if expire < 0:
 | 
			
		||||
            with self._lock:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,13 +9,6 @@ TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH = 0x0008    # 用户名+密码+OATH
 | 
			
		|||
APP_MODE_NORMAL = 1
 | 
			
		||||
APP_MODE_MAINTENANCE = 2
 | 
			
		||||
 | 
			
		||||
# ==========================================================================
 | 
			
		||||
# 用户账号状态
 | 
			
		||||
# ==========================================================================
 | 
			
		||||
USER_STATE_NORMAL = 1  # 正常状态
 | 
			
		||||
USER_STATE_LOCKED = 2  # 锁定(例如密码连错n次)
 | 
			
		||||
USER_STATE_DISABLED = 3  # 禁用
 | 
			
		||||
 | 
			
		||||
# ==========================================================================
 | 
			
		||||
# 远程主机账号认证方式
 | 
			
		||||
# ==========================================================================
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ from app.logic.auth.captcha import tp_captcha_generate_image
 | 
			
		|||
from app.model import user
 | 
			
		||||
from app.model import syslog
 | 
			
		||||
from app.logic.auth.password import tp_password_verify
 | 
			
		||||
from app.base.utils import tp_timestamp_utc_now
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LoginHandler(TPBaseHandler):
 | 
			
		||||
| 
						 | 
				
			
			@ -53,68 +54,86 @@ class LoginHandler(TPBaseHandler):
 | 
			
		|||
 | 
			
		||||
class DoLoginHandler(TPBaseJsonHandler):
 | 
			
		||||
    def post(self):
 | 
			
		||||
        sys_cfg = get_cfg().sys
 | 
			
		||||
 | 
			
		||||
        args = self.get_argument('args', None)
 | 
			
		||||
        if args is not None:
 | 
			
		||||
            try:
 | 
			
		||||
                args = json.loads(args)
 | 
			
		||||
            except:
 | 
			
		||||
                return self.write_json(TPE_JSON_FORMAT, '参数错误')
 | 
			
		||||
        if args is None:
 | 
			
		||||
            return self.write_json(TPE_PARAM)
 | 
			
		||||
 | 
			
		||||
            try:
 | 
			
		||||
                login_type = args['type']
 | 
			
		||||
                captcha = args['captcha'].strip()
 | 
			
		||||
                username = args['username'].strip()
 | 
			
		||||
                password = args['password']
 | 
			
		||||
                oath = args['oath'].strip()
 | 
			
		||||
                remember = args['remember']
 | 
			
		||||
            except:
 | 
			
		||||
                return self.write_json(TPE_PARAM, '参数错误')
 | 
			
		||||
        else:
 | 
			
		||||
            return self.write_json(TPE_PARAM, '参数错误')
 | 
			
		||||
        try:
 | 
			
		||||
            args = json.loads(args)
 | 
			
		||||
        except:
 | 
			
		||||
            return self.write_json(TPE_JSON_FORMAT, '参数错误')
 | 
			
		||||
 | 
			
		||||
        _tmp = {'username': username, 'surname': username}
 | 
			
		||||
        try:
 | 
			
		||||
            login_type = args['type']
 | 
			
		||||
            captcha = args['captcha'].strip()
 | 
			
		||||
            username = args['username'].strip().lower()
 | 
			
		||||
            password = args['password']
 | 
			
		||||
            oath = args['oath'].strip()
 | 
			
		||||
            remember = args['remember']
 | 
			
		||||
        except:
 | 
			
		||||
            return self.write_json(TPE_PARAM)
 | 
			
		||||
 | 
			
		||||
        if login_type not in [TP_LOGIN_AUTH_USERNAME_PASSWORD,
 | 
			
		||||
                              TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA,
 | 
			
		||||
                              TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH,
 | 
			
		||||
                              TP_LOGIN_AUTH_USERNAME_OATH
 | 
			
		||||
                              ]:
 | 
			
		||||
            return self.write_json(TPE_PARAM, '未知的认证方式')
 | 
			
		||||
 | 
			
		||||
        if login_type == TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA:
 | 
			
		||||
            oath = None
 | 
			
		||||
            code = self.get_session('captcha')
 | 
			
		||||
            if code is None:
 | 
			
		||||
                return self.write_json(TPE_CAPTCHA_EXPIRED, '验证码已失效')
 | 
			
		||||
            self.del_session('captcha')
 | 
			
		||||
            if code.lower() != captcha.lower():
 | 
			
		||||
                return self.write_json(TPE_CAPTCHA_MISMATCH, '验证码错误')
 | 
			
		||||
        elif login_type == TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH:
 | 
			
		||||
        elif login_type in [TP_LOGIN_AUTH_USERNAME_OATH, TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH]:
 | 
			
		||||
            if len(oath) == 0:
 | 
			
		||||
                return self.write_json(TPE_OATH_MISMATCH, '未提供身份验证器动态验证码')
 | 
			
		||||
        else:
 | 
			
		||||
            return self.write_json(TPE_PARAM, '参数错误')
 | 
			
		||||
 | 
			
		||||
        self.del_session('captcha')
 | 
			
		||||
 | 
			
		||||
        if len(username) == 0:
 | 
			
		||||
            return self.write_json(TPE_PARAM, '未提供登录用户名')
 | 
			
		||||
 | 
			
		||||
        err, user_info = user.get_by_username(username)
 | 
			
		||||
        # if user_info is None:
 | 
			
		||||
        #     return self.write_json(TPE_USER_AUTH)
 | 
			
		||||
        if err != TPE_OK:
 | 
			
		||||
            if err == TPE_NOT_EXISTS:
 | 
			
		||||
                syslog.sys_log(_tmp, self.request.remote_ip, TPE_NOT_EXISTS, '登录失败,用户`{}`不存在'.format(username))
 | 
			
		||||
                syslog.sys_log({'username': username, 'surname': username}, self.request.remote_ip, TPE_NOT_EXISTS, '登录失败,用户`{}`不存在'.format(username))
 | 
			
		||||
            return self.write_json(err)
 | 
			
		||||
 | 
			
		||||
        if user_info['state'] == USER_STATE_LOCKED:
 | 
			
		||||
            syslog.sys_log(_tmp, self.request.remote_ip, TPE_USER_LOCKED, '登录失败,用户已被锁定')
 | 
			
		||||
            return self.write_json(TPE_USER_LOCKED)
 | 
			
		||||
        elif user_info['state'] == USER_STATE_DISABLED:
 | 
			
		||||
            syslog.sys_log(_tmp, self.request.remote_ip, TPE_USER_DISABLED, '登录失败,用户已被禁用')
 | 
			
		||||
        if user_info['state'] == TP_STATE_LOCKED:
 | 
			
		||||
            # 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息
 | 
			
		||||
            if sys_cfg.login.lock_timeout != 0:
 | 
			
		||||
                if tp_timestamp_utc_now() - user_info.lock_time > sys_cfg.login.lock_timeout * 60:
 | 
			
		||||
                    user_info.fail_count = 0
 | 
			
		||||
                    user_info.state = TP_STATE_NORMAL
 | 
			
		||||
            if user_info['state'] == TP_STATE_LOCKED:
 | 
			
		||||
                syslog.sys_log(user_info, self.request.remote_ip, TPE_USER_LOCKED, '登录失败,用户已被锁定')
 | 
			
		||||
                return self.write_json(TPE_USER_LOCKED)
 | 
			
		||||
        elif user_info['state'] == TP_STATE_DISABLED:
 | 
			
		||||
            syslog.sys_log(user_info, self.request.remote_ip, TPE_USER_DISABLED, '登录失败,用户已被禁用')
 | 
			
		||||
            return self.write_json(TPE_USER_DISABLED)
 | 
			
		||||
        elif user_info['state'] != USER_STATE_NORMAL:
 | 
			
		||||
            syslog.sys_log(_tmp, self.request.remote_ip, TPE_FAILED, '登录失败,系统内部错误')
 | 
			
		||||
        elif user_info['state'] != TP_STATE_NORMAL:
 | 
			
		||||
            syslog.sys_log(user_info, self.request.remote_ip, TPE_FAILED, '登录失败,系统内部错误')
 | 
			
		||||
            return self.write_json(TPE_FAILED)
 | 
			
		||||
 | 
			
		||||
        if login_type == TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA:
 | 
			
		||||
        err_msg = ''
 | 
			
		||||
        if login_type in [TP_LOGIN_AUTH_USERNAME_PASSWORD, TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA, TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH]:
 | 
			
		||||
            if not tp_password_verify(password, user_info['password']):
 | 
			
		||||
                syslog.sys_log(_tmp, self.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误!')
 | 
			
		||||
                err, is_locked = user.update_fail_count(self, user_info)
 | 
			
		||||
                if is_locked:
 | 
			
		||||
                    err_msg = '用户被临时锁定!'
 | 
			
		||||
                syslog.sys_log(user_info, self.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误!{}'.format(err_msg))
 | 
			
		||||
                return self.write_json(TPE_USER_AUTH)
 | 
			
		||||
        elif login_type == TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH:
 | 
			
		||||
        elif login_type in [TP_LOGIN_AUTH_USERNAME_OATH, TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH]:
 | 
			
		||||
            if not tp_oath_verify_code(user_info['oath_secret'], oath):
 | 
			
		||||
                syslog.sys_log(_tmp, self.request.remote_ip, TPE_OATH_MISMATCH, "登录失败,身份验证器动态验证码错误!")
 | 
			
		||||
                err, is_locked = user.update_fail_count(self, user_info)
 | 
			
		||||
                if is_locked:
 | 
			
		||||
                    err_msg = '用户被临时锁定!'
 | 
			
		||||
                syslog.sys_log(user_info, self.request.remote_ip, TPE_OATH_MISMATCH, "登录失败,身份验证器动态验证码错误!{}".format(err_msg))
 | 
			
		||||
                return self.write_json(TPE_OATH_MISMATCH)
 | 
			
		||||
 | 
			
		||||
        self._user = user_info
 | 
			
		||||
| 
						 | 
				
			
			@ -122,12 +141,9 @@ class DoLoginHandler(TPBaseJsonHandler):
 | 
			
		|||
        del self._user['password']
 | 
			
		||||
        del self._user['oath_secret']
 | 
			
		||||
 | 
			
		||||
        print('00000', self._user)
 | 
			
		||||
 | 
			
		||||
        if remember:
 | 
			
		||||
            self.set_session('user', self._user, 12 * 60 * 60)
 | 
			
		||||
        else:
 | 
			
		||||
            # TODO: 使用系统配置项中的默认会话超时
 | 
			
		||||
            self.set_session('user', self._user)
 | 
			
		||||
 | 
			
		||||
        user.update_login_info(self, user_info['id'])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,14 +2,12 @@
 | 
			
		|||
 | 
			
		||||
# import hashlib
 | 
			
		||||
 | 
			
		||||
from app.const import *
 | 
			
		||||
from app.base.logger import log
 | 
			
		||||
# from app.base.configs import get_cfg
 | 
			
		||||
from app.base.configs import get_cfg
 | 
			
		||||
from app.base.db import get_db, SQL
 | 
			
		||||
from app.model import syslog
 | 
			
		||||
# from app.logic.auth.oath import tp_oath_verify_code
 | 
			
		||||
# from app.logic.auth.password import tp_password_generate_secret, tp_password_verify
 | 
			
		||||
from app.base.logger import log
 | 
			
		||||
from app.base.utils import tp_timestamp_utc_now
 | 
			
		||||
from app.const import *
 | 
			
		||||
from app.model import syslog
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_user_info(user_id):
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +30,7 @@ def get_user_info(user_id):
 | 
			
		|||
 | 
			
		||||
def get_by_username(username):
 | 
			
		||||
    s = SQL(get_db())
 | 
			
		||||
    s.select_from('user', ['id', 'type', 'auth_type', 'username', 'surname', 'password', 'oath_secret', 'role_id', 'state', 'email', 'create_time', 'last_login', 'last_ip', 'last_chpass', 'mobile', 'qq', 'wechat', 'desc'], alt_name='u')
 | 
			
		||||
    s.select_from('user', ['id', 'type', 'auth_type', 'username', 'surname', 'password', 'oath_secret', 'role_id', 'state', 'fail_count', 'lock_time', 'email', 'create_time', 'last_login', 'last_ip', 'last_chpass', 'mobile', 'qq', 'wechat', 'desc'], alt_name='u')
 | 
			
		||||
    s.left_join('role', ['name', 'privilege'], join_on='r.id=u.role_id', alt_name='r', out_map={'name': 'role'})
 | 
			
		||||
    s.where('u.username="{}"'.format(username))
 | 
			
		||||
    err = s.query()
 | 
			
		||||
| 
						 | 
				
			
			@ -249,11 +247,10 @@ def set_password(handler, user_id, password):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def update_login_info(handler, user_id):
 | 
			
		||||
 | 
			
		||||
    db = get_db()
 | 
			
		||||
    _time_now = tp_timestamp_utc_now()
 | 
			
		||||
 | 
			
		||||
    sql = 'UPDATE `{}user` SET last_login=login_time, last_ip=login_ip, login_time={login_time}, login_ip="{ip}" WHERE id={user_id};' \
 | 
			
		||||
    sql = 'UPDATE `{}user` SET fail_count=0, last_login=login_time, last_ip=login_ip, login_time={login_time}, login_ip="{ip}" WHERE id={user_id};' \
 | 
			
		||||
          ''.format(db.table_prefix,
 | 
			
		||||
                    login_time=_time_now, ip=handler.request.remote_ip, user_id=user_id
 | 
			
		||||
                    )
 | 
			
		||||
| 
						 | 
				
			
			@ -285,6 +282,29 @@ def update_users_state(handler, user_ids, state):
 | 
			
		|||
        return TPE_DATABASE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_fail_count(handler, user_info):
 | 
			
		||||
    db = get_db()
 | 
			
		||||
    sys_cfg = get_cfg().sys
 | 
			
		||||
    sql_list = []
 | 
			
		||||
    is_locked = False
 | 
			
		||||
    fail_count = user_info.fail_count + 1
 | 
			
		||||
 | 
			
		||||
    sql = 'UPDATE `{}user` SET fail_count={count} WHERE id={uid};' \
 | 
			
		||||
          ''.format(db.table_prefix, count=fail_count, uid=user_info.id)
 | 
			
		||||
    sql_list.append(sql)
 | 
			
		||||
 | 
			
		||||
    if sys_cfg.login.retry != 0 and fail_count >= sys_cfg.login.retry:
 | 
			
		||||
        is_locked = True
 | 
			
		||||
        sql = 'UPDATE `{}user` SET state={state}, lock_time={lock_time} WHERE id={uid};' \
 | 
			
		||||
              ''.format(db.table_prefix, state=TP_STATE_LOCKED, lock_time=tp_timestamp_utc_now(), uid=user_info.id)
 | 
			
		||||
        sql_list.append(sql)
 | 
			
		||||
 | 
			
		||||
    if db.transaction(sql_list):
 | 
			
		||||
        return TPE_OK, is_locked
 | 
			
		||||
    else:
 | 
			
		||||
        return TPE_DATABASE, is_locked
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def remove_users(handler, users):
 | 
			
		||||
    s = SQL(get_db())
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -587,7 +607,7 @@ def get_group_with_member(sql_filter, sql_order, sql_limit):
 | 
			
		|||
    for g in sg.recorder:
 | 
			
		||||
        g['member_count'] = 0
 | 
			
		||||
        g['members'] = []
 | 
			
		||||
        g['_mid'] = []    # 临时使用,构建此组的前5个成员的id
 | 
			
		||||
        g['_mid'] = []  # 临时使用,构建此组的前5个成员的id
 | 
			
		||||
 | 
			
		||||
    # 对于本次要返回的用户组,取其中每一个组内成员的基本信息(id/用户名/真实名称等)
 | 
			
		||||
    groups = [g['id'] for g in sg.recorder]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue