Exemplo n.º 1
0
 def __init__(self):
     self.sserver = SServer()
     self.strade = STrade()
     self.suser = SUser()
     self.pay = WeixinPay(APPID, MCH_ID, MCH_KEY, notify_url,
                          '/home/admin/tool/apiclient_key.pem',
                          '/home/admin/tool/apiclient_cert.pem')  # 后两个参数可选
Exemplo n.º 2
0
 def weixin_callback():
     """通过code, 获取用户信息"""
     args = parameter_required(('code', ))
     code = args.get('code')
     try:
         data = wxlogin.access_token(code)
         print(data)
         data = wxlogin.user_info(data.access_token, data.openid)
         state = args.get('state').split('P')
         usid = state[0]
         redirect_url = state[1]
         to_model = {
             'UScity': data.get('city'),
             'WXopenid': data.get('openid'),
             'WXnickname': data.get('nickname'),
             'USnickname': data.get('nickname'),
             'USheader': data.get('headimgurl'),
             'WXprovice': data.get('province')
         }
         to_model['USgender'] = 0 if data.get('sex') == 1 else 1
         suser = SUser()
         updated = suser.update_user_by_usid(usid, to_model)
         return redirect(redirect_url)
     except WeixinLoginError as e:
         current_app.logger.error(request.url)
         # raise PARAMS_ERROR(u'登录出现错误')
         return redirect(HTTP_HOST)
Exemplo n.º 3
0
class MUserManage(Resource):
    def __init__(self):
        self.suser = SUser()

    def post(self):
        if not is_admin():
            raise TOKEN_ERROR('请使用管理员登录')
        data = parameter_required(('password', ))
        hash_pass = generate_password_hash(data.get('password'))
        admin = self.suser.update_admin_by_adid(request.user.id, {
            'ADpassword':hash_pass
        })
        return jsonify({
            'message': '修改成功',
            'status': 200
        })
Exemplo n.º 4
0
class CTradeBase(object):
    def __init__(self):
        self.strade = STrade()
        self.sserver = SServer()
        self.scity = SCity()
        self.suser = SUser()
        self.pay = WeixinPay(APPID, MCH_ID, MCH_KEY, notify_url,
                             '/home/admin/tool/apiclient_key.pem',
                             '/home/admin/tool/apiclient_cert.pem')  # 后两个参数可选

    def get_appointment_list(self):
        """后台获取预约列表"""
        # 此处将改用for循环 todo
        if not is_admin():
            raise TOKEN_ERROR(u'请使用管理员登录')
        data = parameter_required()
        data['page_num'] = int(data.get('page', 1))
        data['page_size'] = int(data.get('count', 15))
        usid = data.get('usid')
        status = data.get('status')
        data['status'] = status
        server_type = data.get('type')
        if server_type == 'mover':
            order_list = self.strade.get_mover_serverlist_by_usid(usid, data)
            for mover_order in order_list:
                mover_order.clean.add('UMTid', 'SMSid', 'UMTstarttime',
                                      'UMTmoveoutaddr', 'UMTmoveinaddr',
                                      'UMTphone', 'UMTspecialwish',
                                      'UMTpreviewprice', 'UMTmoveinlocation',
                                      'UMTmoveoutlocation', 'USid',
                                      'UMTcreatetime')
                mover_order.fill(
                    getattr(self.sserver.get_mover_by_smsid(mover_order.SMSid),
                            'SMStitle', u'未知'), 'name'),
                mover_order.fill('mover', 'type')
                mover_order.fill(
                    SERVER_STATUS.get(mover_order.UMTstatus, u'其它'),
                    'umtstatus')
                setattr(mover_order, 'createtime', mover_order.UMTcreatetime)
        elif server_type == 'fixer':
            order_list = self.strade.get_fixer_serverlist_by_usid(usid, data)
            for fixer_order in order_list:
                setattr(fixer_order, 'createtime', fixer_order.UFTcreatetime)
                fixer_order.fill(u'邻家维修', 'name')
                setattr(fixer_order, 'UFTstatus',
                        SERVER_STATUS.get(fixer_order.UFTstatus, u'其它'))
                fixer_order.fill(u'fixer', 'type')
        elif server_type == 'cleaner':
            order_list = self.strade.get_clean_serverlist_by_usid(usid, data)
            for clean_order in order_list:
                clean_order.fill(
                    getattr(
                        self.sserver.get_cleanerserver_by_sceid(
                            clean_order.SCEid), 'SCMtitle', u'未知'), 'name')
                setattr(clean_order, 'UCTstatus',
                        SERVER_STATUS.get(clean_order.UCTstatus))
                setattr(clean_order, 'createtime', clean_order.UCTcreatetime)
                clean_order.fill('cleaner', 'type')
        else:
            mover_order_list = self.strade.get_mover_serverlist_by_usid(
                usid, {'status': status})
            fixer_order_list = self.strade.get_fixer_serverlist_by_usid(
                usid, {'status': status})
            cleaner_list = self.strade.get_clean_serverlist_by_usid(
                usid, {'status': status})
            order_list = mover_order_list + fixer_order_list + cleaner_list
            len_order_list = len(order_list)
            page_size = data['page_size']
            start = (data['page_num'] - 1) * data['page_size']
            end = start + page_size
            if end > len_order_list:
                end = len_order_list
            if start > end:
                start = end
            order_list = order_list[start:end]
            # 搬家
            for mover_order in mover_order_list:
                mover_order.clean.add('UMTid', 'SMSid', 'UMTstarttime',
                                      'UMTmoveoutaddr', 'UMTmoveinaddr',
                                      'UMTphone', 'UMTspecialwish',
                                      'UMTpreviewprice', 'UMTmoveinlocation',
                                      'UMTmoveoutlocation', 'USid',
                                      'UMTcreatetime')
                mover_order.fill(
                    getattr(self.sserver.get_mover_by_smsid(mover_order.SMSid),
                            'SMStitle', u'未知'), 'name'),
                mover_order.fill('mover', 'type')
                mover_order.fill(SERVER_STATUS.get(mover_order.UMTstatus),
                                 'umtstatus')
                setattr(mover_order, 'createtime', mover_order.UMTcreatetime)
            for clean_order in cleaner_list:
                clean_order.fill(
                    getattr(
                        self.sserver.get_cleanerserver_by_sceid(
                            clean_order.SCEid), 'SCMtitle', u'未知'), 'name')
                setattr(clean_order, 'UCTstatus',
                        SERVER_STATUS.get(clean_order.UCTstatus))
                setattr(clean_order, 'createtime', clean_order.UCTcreatetime)
                clean_order.fill('cleaner', 'type')
            # 维修
            for fixer_order in fixer_order_list:
                setattr(fixer_order, 'createtime', fixer_order.UFTcreatetime)
                fixer_order.fill(u'邻家维修', 'name')
                setattr(fixer_order, 'UFTstatus',
                        SERVER_STATUS.get(fixer_order.UFTstatus))
                fixer_order.fill(u'fixer', 'type')
            # 员工id 姓名.
            # map(lambda x: setattr( x, 'staff', self.suser.get_staff_by_stfid(x.STFid)) if not x.STFid order_list)
        for order in order_list:
            stfid = order.STFid
            staff = {}
            if stfid:
                staff = self.suser.get_staff_by_stfid(stfid)
                if staff:
                    staff = staff.clean.add('STFid', 'STFname')
            setattr(order, 'staff', staff)
            order.add('staff')
        order_list = sorted(order_list,
                            key=lambda x: x.createtime,
                            reverse=True)
        # request.page_count = math.ceil(float(len_order_list) / page_size)
        # request.all_count = len_order_list
        return Success(u'获取列表成功', order_list)

    def get_my_oppintment(self):
        """获得我的预约搬家, 维修, 清洁 type=mover, fixer, cleaner"""
        if is_admin():
            return TOKEN_ERROR(u'普通用户查看')
        if is_tourist():
            return TOKEN_ERROR(u'请登录后查看')
        data = parameter_required()
        data['page_num'] = int(data.get('page', 1))
        data['page_size'] = int(data.get('count', 15))
        usid = request.user.id
        server_type = data.get('type')
        if server_type == 'mover':
            order_list = self.strade.get_mover_serverlist_by_usid(usid, data)
            map(
                lambda x: x.clean.
                add('UMTid', 'SMSid', 'UMTstarttime', 'UMTmoveoutaddr',
                    'UMTmoveinaddr', 'UMTphone', 'UMTspecialwish',
                    'UMTpreviewprice', 'UMTmoveinlocation',
                    'UMTmoveoutlocation', 'USid', 'UMTcreatetime', 'Citynum'),
                order_list)
            map(lambda x: x.fill(SERVER_STATUS.get(x.UMTstatus), 'umtstatus'),
                order_list)
            map(
                lambda x: x.fill(
                    self.sserver.get_mover_by_smsid(x.SMSid).SMStitle, 'name'),
                order_list)
            map(lambda x: x.fill('mover', 'type'), order_list)
        elif server_type == 'fixer':
            order_list = self.strade.get_fixer_serverlist_by_usid(usid, data)
            map(
                lambda x: setattr(x, 'UFTstatus', SERVER_STATUS.get(
                    x.UFTstatus)), order_list)
            map(lambda x: x.fill(u'fixer', 'type'), order_list)
        elif server_type == 'cleaner':
            order_list = self.strade.get_clean_serverlist_by_usid(usid, data)
            map(
                lambda x: setattr(x, 'UCTstatus', SERVER_STATUS.get(
                    x.UCTstatus)), order_list)
            map(
                lambda x: x.fill(
                    self.sserver.get_cleanerserver_by_sceid(x.SCEid).SCMtitle,
                    'name'), order_list)
            map(lambda x: x.fill('cleaner', 'type'), order_list)
        else:
            mover_order_list = self.strade.get_mover_serverlist_by_usid(
                usid, data)
            fixer_order_list = self.strade.get_fixer_serverlist_by_usid(
                usid, data)
            cleaner_list = self.strade.get_clean_serverlist_by_usid(usid, data)
            order_list = mover_order_list + fixer_order_list + cleaner_list
            len_order_list = len(order_list)
            page_size = data['page_size']
            start = (data['page_num'] - 1) * data['page_size']
            end = start + page_size
            if end > len_order_list:
                end = len_order_list
            if start > end:
                start = end
            order_list = order_list[start:end]
            # 搬家
            for mover_order in mover_order_list:
                mover_order.clean.add('UMTid', 'SMSid', 'UMTstarttime',
                                      'UMTmoveoutaddr', 'UMTmoveinaddr',
                                      'UMTphone', 'UMTspecialwish',
                                      'UMTpreviewprice', 'UMTmoveinlocation',
                                      'UMTmoveoutlocation', 'USid',
                                      'UMTcreatetime', 'Citynum')
                mover_order.fill(
                    getattr(self.sserver.get_mover_by_smsid(mover_order.SMSid),
                            'SMStitle', u'未知'), 'name')
                mover_order.fill(SERVER_STATUS.get(mover_order.UMTstatus),
                                 'umtstatus')
                setattr(mover_order, 'createtime', mover_order.UMTcreatetime)
                mover_order.fill('mover', 'type')
                # map(lambda x: x.fill(getattr(self.sserver.get_mover_by_smsid(x.SMSid), 'SMStitle', u'未知'), 'name'),
                #     mover_order_list)
                # map(lambda x: x.fill('mover', 'type'), mover_order_list)
                # map(lambda x: x.fill(SERVER_STATUS.get(x.UMTstatus), 'umtstatus'), mover_order_list)
                # map(lambda x: setattr(x, 'createtime', x.UMTcreatetime), mover_order_list)
            # 清洁
            for cleaner_order in cleaner_list:
                cleaner_order.fill(
                    getattr(
                        self.sserver.get_cleanerserver_by_sceid(
                            cleaner_order.SCEid), 'SCMtitle', u'未知'), 'name')
                setattr(cleaner_order, 'UCTstatus',
                        SERVER_STATUS.get(cleaner_order.UCTstatus))
                setattr(cleaner_order, 'createtime',
                        cleaner_order.UCTcreatetime)
                cleaner_order.fill('cleaner', 'type')
            # map(lambda x: x.fill(getattr(self.sserver.get_cleanerserver_by_sceid(x.SCEid), 'SCMtitle', u'未知'), 'name'),
            #     cleaner_list)
            # map(lambda x: setattr(x, 'UCTstatus', SERVER_STATUS.get(x.UCTstatus)), cleaner_list)
            # map(lambda x: setattr(x, 'createtime', x.UCTcreatetime), cleaner_list)
            # map(lambda x: x.fill('cleaner', 'type'), cleaner_list)
            # 维修
            for fix_order in fixer_order_list:
                x = fix_order
                setattr(fix_order, 'createtime', fix_order.UFTcreatetime)
                fix_order.fill(u'邻家维修', 'name')
                setattr(x, 'UFTstatus', SERVER_STATUS.get(x.UFTstatus))
                x.fill(u'fixer', 'type')
                # map(lambda x: setattr(x, 'createtime', x.UFTcreatetime), fixer_order_list)
                # map(lambda x: x.fill(u'邻家维修', 'name'), fixer_order_list)
                # map(lambda x: setattr(x, 'UFTstatus', SERVER_STATUS.get(x.UFTstatus)), fixer_order_list)
                # map(lambda x: x.fill(u'fixer', 'type'), fixer_order_list)
            order_list = sorted(order_list, key=lambda x: x.createtime)
            request.page_count = math.ceil(float(len_order_list) / page_size)
            request.all_count = len_order_list
            order_list = sorted(order_list, key=lambda x: x.createtime)
        for order in order_list:
            stfid = order.STFid
            staff = {}
            if stfid:
                staff = self.suser.get_staff_by_stfid(stfid).clean.add(
                    'STFid', 'STFname')
            setattr(order, 'staff', staff)
            order.add('staff')
        return Success(u'获取列表成功', order_list)

    def get_appointment_one(self):
        """获取单条订单"""
        if is_tourist():
            raise TOKEN_ERROR(u'请登录')
        data = parameter_required()
        if 'uctid' in data:
            uctid = data.get('uctid')
            order = self.strade.get_clean_order_by_uctid(uctid)
            if not order:
                raise NOT_FOUND(u'该订单不存在')
            order.UCTstatus = SERVER_STATUS.get(order.UCTstatus)
            sceid = order.SCEid
            cleaner_server = self.sserver.get_cleanerserver_by_sceid(sceid)
            order.fill('clener', 'type')
            order.fill(getattr(cleaner_server, 'SCMtitle', ''), 'name')
        elif 'uftid' in data:
            uftid = data.get('uftid')
            order = self.strade.get_fixer_order_by_uftid(uftid)
            if not order:
                raise NOT_FOUND(u'该订单不存在')
            order.UFTstatus = SERVER_STATUS.get(order.UFTstatus)
            order.fill('fixer', 'type')
            order.fill('邻家维修', 'name')
        elif 'umtid' in data:
            umtid = data.get('umtid')
            order = self.strade.get_mover_order_by_umtid(umtid)
            if not order:
                raise NOT_FOUND(u'该订单不存在')
            order.UMTstatus = SERVER_STATUS.get(order.UMTstatus)
            order.fill('mover', 'type')
            smsid = order.SMSid
            mover_server = self.sserver.get_mover_by_smsid(smsid)
            order.fill(getattr(mover_server, 'SMStitle', ''), 'name')
            order.fill('type', 'mover')
        else:
            return PARAMS_ERROR()
        if not is_admin():
            if request.user.id != order.USid:
                raise NOT_FOUND(u'它人订单')
        # 工作人员
        staff = {}
        stfid = order.STFid
        if stfid:
            staff = self.suser.get_staff_by_stfid(stfid).clean.add(
                'STFid', 'STFname')
        order.fill(staff, 'staff')
        return Success(u'获取订单成功', {'order': order})

    def point_staff(self):
        """给订单指定工作人员"""
        if not is_admin():
            raise TOKEN_ERROR(u'请使用管理员登录')
        data = parameter_required(('stfid', ))
        stfid = data.get('stfid')
        staff = self.suser.get_staff_by_stfid(stfid)
        if not staff:
            raise NOT_FOUND(u'不存在的工作人员')
        if staff.STFisblocked:
            raise NOT_FOUND(u'黑名单里的工作人员')
        response = {'stfid': stfid}
        # 如果是搬家服务
        if 'umtid' in data:
            umtid = data.get('umtid')
            mover_order = self.strade.get_mover_order_by_umtid(umtid)
            if mover_order.UMTstatus != 1:  # 只有等待服务的订单才可以制定
                raise PARAMS_ERROR(u'当前订单状态为{}, 只可以指定等待服务中的订单'.format(
                    SERVER_STATUS.get(mover_order.UMTstatus)))
            updated = self.strade.update_movertrade_detail_by_umtid(
                umtid, {'STFid': stfid})
            response['type'] = 'mover'
        elif 'uftid' in data:
            # 如果是维修
            uftid = data.get('uftid')
            fixer_order = self.strade.get_fixer_order_by_uftid(uftid)
            if fixer_order.UFTstatus != 1:
                raise PARAMS_ERROR(u'当前订单状态为{}, 只可以指定等待服务中的订单'.format(
                    SERVER_STATUS.get(fixer_order.UMTstatus)))
            updated = self.strade.update_fixerorder_detail_by_uftid(
                uftid, {'STFid': stfid})
            response['type'] = 'fixer'
        elif 'uctid' in data:
            # 如果是保洁
            uctid = data.get('uctid')
            cleaner_order = self.strade.get_clean_order_by_uctid(uctid)
            if cleaner_order.UCTstatus != 1:
                raise PARAMS_ERROR(u'当前订单状态为{}, 只可以指定等待服务中的订单'.format(
                    SERVER_STATUS.get(cleaner_order.UMTstatus)))
            updated = self.strade.update_cleanorder_detail_by_uctid(
                uctid, {'STFid': stfid})
            response['type'] = 'cleaner'
        else:
            # 其他 参数有误
            raise PARAMS_ERROR(u'订单参数有误')
        msg = u'更新成功' if updated else u'无此记录'
        return Success(msg, response)

    @staticmethod
    def _allow_starttime(str_time):
        try:
            startime = datetime.strptime(str_time, format_for_db)
        except Exception as e:
            raise PARAMS_ERROR(str(str_time) + u'时间格式不正确')
        time_on_road_seconds = (startime - datetime.now()).total_seconds()
        if MOVER_APPOINT_MIN_TIME_ON_ROAD < time_on_road_seconds < MOVER_APPOINT_MAX_TIME_ON_ROAD:
            return str_time
        raise PARAMS_ERROR(u'时间不合理')

    @staticmethod
    def _allow_order_status(old, new):
        if old == 0:
            # 0: u'待支付', 1: u'等待服务', 2: u'服务完成', 3: u'申请退款', 4: u'退款中', 5: u'交易关闭'
            allow = [1]
        elif old == 1:
            allow = [2, 4]
        elif old == 2:
            allow = []
        elif old == 3:
            allow = [2, 4]
        elif old == 4:
            allow = [5]
        else:
            allow = [0, 1, 2, 3, 4, 5]
        if new not in allow:
            raise PARAMS_ERROR(u'状态不合理, 当前状态为: {} '
                               u''.format(SERVER_STATUS.get(old)))

    @staticmethod
    def refund():
        # todo 退款状态
        pass
Exemplo n.º 5
0
 def __init__(self):
     self.suser = SUser()
Exemplo n.º 6
0
 def __init__(self):
     self.sroom = SRoom()
     self.suser = SUser()
     self.scity = SCity()
     self.sindex = SIndex()
Exemplo n.º 7
0
class CPay(object):
    def __init__(self):
        self.sserver = SServer()
        self.strade = STrade()
        self.suser = SUser()
        self.pay = WeixinPay(APPID, MCH_ID, MCH_KEY, notify_url,
                             '/home/admin/tool/apiclient_key.pem',
                             '/home/admin/tool/apiclient_cert.pem')  # 后两个参数可选

    def pay_for_service(self):
        data = parameter_required()
        if is_tourist():
            raise TOKEN_ERROR()
        if is_admin():
            raise AUTHORITY_ERROR(u'请使用普通用户登陆')
        usid = request.user.id
        user = self.suser.get_user_by_usid(usid)
        openid = user.WXopenid
        if 'umtid' in data:
            umtid = data.get('umtid')
            usermoverorder = self.strade.get_mover_order_by_umtid(umtid)
            if not usermoverorder or usermoverorder.UMTstatus != 0:
                raise NOT_FOUND()
            total_fee = usermoverorder.UMTpreviewprice
            out_trade_no = self.pay.nonce_str
            self.strade.update_movertrade_detail_by_umtid(
                umtid, {'sn': out_trade_no})
            body = u'邻家搬家'
            attach = u'mover'
        elif 'uctid' in data:
            uctid = data.get('uctid')
            user_clean_order = self.strade.get_clean_order_by_uctid(uctid)
            if not user_clean_order or user_clean_order.UCTstatus != 0:
                raise NOT_FOUND()
            total_fee = user_clean_order.UCTprice
            out_trade_no = self.pay.nonce_str
            self.strade.update_cleanorder_detail_by_uctid(
                uctid, {'sn': out_trade_no})
            body = u'cleaner'
            attach = u'cleaner'

        elif 'uftid' in data:
            uftid = data.get('uftid')
            user_fixer_order = self.strade.get_fixer_order_by_uftid(uftid)
            if not user_fixer_order or user_fixer_order.UFTstatus != 0:
                raise NOT_FOUND()
            total_fee = user_fixer_order.UFTprice
            out_trade_no = self.pay.nonce_str
            self.strade.update_fixerorder_detail_by_uftid(
                uftid, {'sn': out_trade_no})
            body = u'fixer'
            attach = u'fixer'
        else:
            raise PARAMS_ERROR()
        try:
            total_fee *= 100
            raw = self.pay.jsapi(trade_type="JSAPI",
                                 openid=openid,
                                 body=body,
                                 out_trade_no=out_trade_no,
                                 total_fee=int(total_fee),
                                 attach=attach,
                                 spbill_create_ip=request.remote_addr)
            res = dict(raw)
            res['paySign'] = res.get('sign')
        except WeixinPayError as e:
            return SYSTEM_ERROR(e.message)
        return Success(res)

    def pay_notify(self):
        data = self.pay.to_dict(request.data)
        generic_log(data)
        if not self.pay.check(data):
            return self.pay.reply(u"签名验证失败", False)
        sn = data.get('out_trade_no')
        paytime = data.get('time_end')
        attach = data.get('attach')
        if attach == u'mover':
            updated = self.strade.update_movertrade_detail_by_sn(
                sn, {
                    'UMTstatus': 1,
                    'paytime': paytime
                })
        elif attach == u'cleaner':
            updated = self.strade.update_cleanerorder_detail_by_sn(
                sn, {
                    'UCTstatus': 1,
                    'paytime': paytime
                })
            pass
        elif attach == u'fixer':
            updated = self.strade.udpate_fixerorder_detail_by_sn(
                sn, {
                    'UFTstatus': 1,
                    'paytime': paytime
                })
        return self.pay.reply("OK", True)

    def check_refund(self):
        """查询是否退款"""
        # if not is_admin():
        #     raise TOKEN_ERROR(u'请使用管理员登录')
        data = parameter_required()
        if 'umtid' in data:
            umtid = data.get('umtid')
            order = self.strade.get_mover_order_by_umtid(umtid)
            if not order or order.UMTstatus != 4:
                raise NOT_FOUND()
            pass
        elif 'uctid' in data:
            uctid = data.get('uctid')
            order = self.strade.get_clean_order_by_uctid(uctid)
            if not order or order.UCTstatus != 4:
                raise NOT_FOUND()
        elif 'uftid' in data:
            uftid = data.get('uftid')
            order = self.strade.get_fixer_order_by_uftid(uftid)
            if not order or order.UFTstatus != 4:
                raise NOT_FOUND()
        else:
            raise PARAMS_ERROR()
        sn = order.sn
        try:
            res = self.pay.refund_query(out_trade_no=sn)
        except WeixinPayError as e:
            raise SYSTEM_ERROR(e.message)
        return Success(data=res)
Exemplo n.º 8
0
 def __init__(self):
     self.suser = SUser()
     self.susercode = SUserCode()
     self.wxlogin = WeixinLogin(APPID, APPSECRET)
Exemplo n.º 9
0
class CUser():
    def __init__(self):
        self.suser = SUser()
        self.susercode = SUserCode()
        self.wxlogin = WeixinLogin(APPID, APPSECRET)

    def admin_login(self):
        """管理员登录"""
        data = parameter_required(('username', 'password'))
        username = data.get('username')
        password = data.get('password')
        admin = self.suser.verify_admin_login(username, password)
        if not admin:
            raise NOT_FOUND(u'用户名或者密码错误')
        level = admin.ADlevel  # 管理员等级
        token = usid_to_token(admin.ADid, 'Admin', level=level)
        return Success(u'获取token成功', {
            'token': token,
            'level': level
        })

    def login(self):
        """登录, 没有用户则自动创建"""
        data = parameter_required(('phone', 'code', 'redirect'), others='ignore')
        phone = str(data.get('phone'))
        code = int(data.get('code'))
        redirect = data.get('redirect', HTTP_HOST)
        usercode = self.susercode.get_active_usercode_by_phone_code(phone, code)
        if not usercode:
            return NOT_FOUND(u'验证码已过期或不正确')
        user = self.suser.get_user_by_phone(phone)
        now_time = datetime.strftime(datetime.now(), format_for_db)
        if not user:  # 如果是新用户
            user_dict = {
                'usid': str(uuid.uuid4()),
                'USphone': str(phone),
                'UScreatetime': now_time,
                'USlastlogin': now_time
            }
            self.suser.add_model('User', user_dict)
            token = usid_to_token(user_dict['usid'])
            state = str(user_dict['usid']) + u'P' + redirect
            redirect_url = self.wxlogin.authorize(API_HOST + "/api/wechat/callback", WXSCOPE, state=state)
            return Success(u'注册成功', status=302, data={
                'token': token,
                'redirect_url': redirect_url
            })
        elif not user.WXopenid:  # 无用户资料
            token = usid_to_token(user.USid)
            state = str(user.USid) + u'P' + redirect
            redirect_url = self.wxlogin.authorize(API_HOST + "/api/wechat/callback", WXSCOPE, state=state)
            return Success(u'注册成功', status=302, data={
                'token': token,
                'redirect_url': redirect_url
            })
        else:  # 老用户
            # 如果是已经存在的用户则记录上次登录时间
            updated = self.suser.update_user_by_phone(phone, {
                'USlastlogin': now_time
            })
            token = usid_to_token(user.USid)
        return Success(u'获取token成功', {
            'token': token
        })

    def get_code(self):
        """发送验证码"""
        data = parameter_required(('phone', ))
        phone = validate_phone(data.get('phone'))
        send = Thread(target=self._async_send_code, args=(phone, ))
        send.start()
        message = u'获取成功'
        return Success(message)
    #
    # def wechat_login(self):
    #     """获取微信跳转链接"""
    #     url = self.wxlogin.authorize(API_HOST + "/user/weixin_callback/", WXSCOPE)
    #     return Success(u'获取跳转链接成功',  {'url': url}, status=302)
    #
    # def weixin_callback(self):
    #     """通过code, 获取用户信息"""
    #     args = parameter_required(('code', ))
    #     code = args.get('code')
    #     try:
    #         data = self.wxlogin.access_token(code)
    #         data = self.wxlogin.user_info(data.access_token, data.openid)
    #         state = args.get('state').split('|')
    #         usid = state[0]
    #         redirect_url = state[1]
    #         to_model = {
    #             'UScity': data.get('city'),
    #             'WXopenid': data.get('openid'),
    #             'WXnickname': data.get('nickname'),
    #             'USnickname': data.get('nickname'),
    #             'USheader': data.get('headimgurl'),
    #             'WXprovice': data.get('province')
    #         }
    #         to_model['USgender'] = 0 if data.get('sex') == 1 else 1
    #         updated = self.suser.update_user_by_usid(usid, to_model)
    #         return redirect(u'http://www.baidu.com')
    #     except WeixinLoginError as e:
    #         # current_app.logger.error(str(data))
    #         # raise PARAMS_ERROR(u'登录出现错误')
    #         return redirect(u'http://www.baidu.com')
    #         return redirect(HTTP_HOST)

    def get_wx_config(self):
        data = request.json
        if not data:
            data = {}
        current_url = data.get('url', request.url)
        mp = WeixinMP(APPID, APPSECRET)
        print(current_url)
        data = {
            'config': mp.jsapi_sign(url=current_url),
            'url': current_url
        }
        response = Success(u'返回签名成功', data)
        return response

    def get_staff_list(self):
        """获取工作人员"""
        data = request.args.to_dict()
        level = data.get('level')
        page = int(data.get('page', 1))
        count = int(data.get('count', 15))
        gender = int(data.get('gender')) if 'gender' in data else None
        city_id = data.get('city_id')
        kw = data.get('kw', '').strip()   # 员工姓名模糊搜索
        staff_list = self.suser.get_staff_list(level, page, count, gender, city_id, kw)
        for staff in staff_list:
            setattr(staff,  'STFlevel', STAFF_TYPE.get(staff.STFlevel, u'其他'))
            setattr(staff, 'STFgender', GENDER_CONFIG.get(staff.STFgender, u'未知'))
        return Success(u'获取工作人员成功', {
            'staff': staff_list
        })

    def add_staff(self):
        """添加工作人员"""
        if not is_admin():
            raise TOKEN_ERROR(u'请使用管理员登录')
        data = parameter_required(('stfname', 'stfmobiel', 'stfaddress', 'stfgender', 'stflevel'), others='allow', forbidden=('STFid', ))
        validate_phone(data.get('stfmobiel'))
        if 'stfphone' in data:
            validate_phone(data.get('stfphone'))
        data['stfid'] = str(uuid.uuid4())
        data['STFcreatetime'] = datetime.strftime(datetime.now(), format_for_db)
        self.suser.add_model('Staff', data)
        return Success(u'添加成功', {
            'stfid': data.get('stfid')
        })

    def update_staff(self):
        """修改工作人员信息"""
        if not is_admin():
            raise TOKEN_ERROR(u'请使用管理员登录')
        json_data = parameter_required(('stfid', ), others='allow')
        stfid = json_data.get('stfid')
        data = {
            'STFname': json_data.get('stfname'),
            'STFmobiel': json_data.get('stfmobiel'),
            'STFphone': json_data.get('stfphone'),
            'STFaddress': json_data.get('stfaddress'),
            'STFgender': json_data.get('stfgender'),
            'STFlevel': json_data.get('stflevel'),
            'ADaddressnum': json_data.get('adaddressnum'),
            'APid': json_data.get('apid'),
            'ADdesc': json_data.get('addesc'),
            'STFisblocked': json_data.get('stfisblocked'),
        }
        data = {
            k: v for k, v in data.items() if v is not None
        }
        staff = self.suser.update_staff_info(stfid, data)
        if not staff:
            return Success(u'无此记录', {
                'stfid': stfid
            })
        else:
            return Success(u'修改成功', {
                'stfid': stfid
            })

    def get_staff_by_id(self):
        if not is_admin():
            raise TOKEN_ERROR(u'请使用管理员登录')
        data = parameter_required(('stfid', ))
        staff = self.suser.get_staff_by_stfid(data.get('stfid'))
        if not staff:
            raise NOT_FOUND(u'无记录')
        staff.all.hide('STFisdelete')
        setattr(staff,  'STFlevel', STAFF_TYPE.get(staff.STFlevel, u'其他'))
        setattr(staff, 'STFgender', GENDER_CONFIG.get(staff.STFgender, u'未知'))
        return Success(u'获取成功', {
            'staff': staff
        })

    def delete_staff(self):
        if not is_admin():
            raise TOKEN_ERROR(u'请使用管理员登录')
        data = parameter_required(('stfid',))
        stfid = data.get('stfid')
        staff = self.suser.delete_staff_by_stfid(stfid)
        if not staff:
            return Success(u'无此记录', {
                'stfid': stfid
            })
        return Success(u'删除成功', {
            'stfid': stfid
        })

    def add_admin(self):
        # 添加管理员, 默认添加0级别管理员
        if not is_hign_level_admin():
            raise TOKEN_ERROR(u'需要高级管理权限')
        required = ['adname', 'adusername', 'adpassword', 'admobiel', 'ademail']
        data = parameter_required(required)
        if self.suser.get_admin_by_adusername(data.get('adusername')):
            raise PARAMS_ERROR(u'用户名重复')

        validate_phone(data.get('admobiel'))
        validate_phone(data.get('adphone'))
        validate_arg('\w+@\w+\.\w+', data.get('ademail'), u'电子邮箱格式不正确')
        data['adlevel'] = 0 or data.get('adlevel')
        if data['adlevel'] >= request.user.level:
            raise AUTHORITY_ERROR()
        data['adid'] = str(uuid.uuid4())
        data['adpassword'] = generate_password_hash(data.get('adpassword'))
        self.suser.add_model('Admin', data)
        return Success(u'添加管理员成功', {
            'adid': data.get('adid')
        })

    def freeze_admin(self):
        """冻结管理员"""
        if not is_hign_level_admin():
            raise TOKEN_ERROR(u'需要高级管理权限')
        data = parameter_required(('adid', ))
        adid = data.get('adid')
        admin = self.suser.get_admin_by_adid(adid)
        if admin and admin.ADlevel >= request.user.level:
            raise AUTHORITY_ERROR()
        freezed = self.suser.freeze_adiin_by_adid(adid)
        msg = u'操作成功' if freezed else u'无此记录'
        return Success(msg, {
            'adid': adid
        })

    def unfreeze_admin(self):
        """管理员解冻"""
        if not is_hign_level_admin():
            raise TOKEN_ERROR(u'需要高级管理权限')
        data = parameter_required(('adid', ))
        adid = data.get('adid')
        admin = self.suser.get_admin_by_adid(adid)
        if admin and admin.ADlevel >= request.user.level:
            raise AUTHORITY_ERROR()
        unfreezed = self.suser.unfreeze_admin_by_adid(adid)
        msg = u'操作成功' if unfreezed else u'无此记录'
        return Success(msg, {
            'adid': adid     
        })
        
    def get_admin_list(self):
        """查看管理员列表"""
        if not is_admin():
            raise TOKEN_ERROR(u'请使用管理员登录')
        data = request.args.to_dict()
        page = data.get('page', 1)
        count = data.get('count', 15)
        freeze_args = data.get('freeze')
        freeze = None
        if freeze_args is not None:
            freeze = False if str(freeze_args) == '0' else True
        admin_list = self.suser.get_admin_list(data.get('level'), freeze, page, count)
        map(lambda x: x.hide('ADpassword'), admin_list)
        return Success(u'ok', {
            'admins': admin_list
        })

    def get_user_list(self):
        """查看普通列表, 筛选参数为: 手机号, 性别, """
        if not is_admin():
            raise TOKEN_ERROR(u'请使用管理员登录')
        data = parameter_required(())
        page = data.get('page', 1)
        count = data.get('count', 15)
        gender = data.get('gender')
        phone = data.get('phone')
        usid = data.get('usid')
        user_list = self.suser.get_user_list(page, count, gender, phone, usid)
        for user in user_list:
            user.all.hide('WXprivilege', 'WXheader', 'WXnickname', 'USaddr', 'USstar', 'UShobby', 'USpassword')
            user.USgender = GENDER_CONFIG.get(user.USgender)
        return Success(u'获取用户列表成功', user_list)

    def get_one_housekeeper(self):
        """获取一个管家"""
        data = parameter_required(('roid', ))
        # staff_list = self.suser.get_staff_list(level=0)  # level 0 表示管家
        # 暂定为随机获取一个管家
        self.sroom = SRoom()
        roid = data.get('roid')
        room = self.sroom.get_room_by_roid(roid)
        if not room:
            raise NOT_FOUND(u'房源不存在')
        stfid = room.STFid
        staff = self.suser.get_staff_by_stfid(stfid)
        if not staff:
            raise NOT_FOUND('未绑定管家')
        staff.clean.add('STFid', 'STFname', 'STFmobiel', 'STFgender')
        return Success(u'获取成功', {
            'housekeeper': staff
        })

    def _async_send_code(self, phone):
        """发送验证码"""
        headers = {
            'Authorization': auth_key
        }
        code = str(random.randint(1111, 9999))
        url = code_url.format(code, phone)
        content_json = requests.post(url, headers=headers).json()
        if content_json.get('return_code') == '00000':
            print(0000)
            data = {
                'UCid': str(uuid.uuid4()),
                'Codenum': int(code),
                'Phone': phone,
                'Createtime': datetime.strftime(datetime.now(), format_for_db)
            }
            self.suser.add_model('UserCode', data)
        else:
            raise SYSTEM_ERROR(traceback.format_exc().decode('unicode-escape'))