Example #1
0
def get_device_list():
    '''
    page: 当前页码
    size: 每页读取数目, 最大不超过50项
    city: 查询的城市 如不传或者为None则查询全部城市
    area: 查询城市所属区域,如不传或者为None则查询该城市全部区域,前置条件必须有城市信息
    start_time: 查询的起始时间段 时间段其实时间必须小于或者等于end_time
    end_time: 查询的结束时间段 时间段必须大于或者等于start_time
    state: 当前设备状态 如 为None 则查询所有状态
    :return:
    '''

    # 同步设备存活状态到mysql中
    DeviceService.sync_device_alive_status()
    return DeviceService.search_list()
Example #2
0
    def to_dict(self):

        to_json = {
            'id': self.id,
            'user_id': self.user_id,
            'device_id': self.device_id,
            'province': self.province,
            'city': self.city,
            'area': self.area,
            'location': self.location,
            'cost_money': self.cost_money,
            'ctime': self.ctime.strftime('%Y-%m-%d %H:%M:%S'),
            'utime': self.utime.strftime('%Y-%m-%d %H:%M:%S'),
            'end_time': self.end_time.strftime('%Y-%m-%d %H:%M:%S'),
            'cost_time': self.cost_time  # 分钟
        }

        item = User.get(self.user_id)
        if item is not None:
            to_json['user'] = item.to_dict()
        item = DeviceService.get_device_by_id(self.device_id)
        if item is not None:
            to_json['device'] = item.to_dict()

        return to_json
Example #3
0
def get_device_game_manage():
    '''
    page: 当前页码
    size: 每页读取数目, 最大不超过50项
    :return:
    '''

    return DeviceService.search_list()
Example #4
0
def get_device_by_id(device_id):
    device = None
    while True:
        try:

            # 先通过设备mac地址查找
            device = DeviceService.get_device_by_code(device_id)
            if device is not None:
                break

            a_id = int(device_id)
            device = DeviceService.get_device_by_id(a_id)
        except Exception as e:
            log.error("设备信息无法转换为 int 类型: device_id = {}".format(device_id))
            log.exception(e)
        break

    if device is None:
        return success(None)

    # 获取设备最新存活状态
    device.alive = DeviceService.get_device_alive_status(device.device_code)
    return success(device.to_dict())
Example #5
0
def keep_alive():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    record_key = request.json.get('token')
    if record_key is None:
        return fail(HTTP_OK, u"not have token!!!")

    device_code = request.json.get('device_code')
    if device_code is None:
        log.error(
            "无法保持心跳, 没有传入device_code: record_key = {}".format(record_key))
        return fail(HTTP_OK, u"not have device_code!!!")

    # 保持心跳
    DeviceService.keep_device_heart(device_code)

    charging = redis_cache_client.get(record_key)
    if charging is None:
        return success({
            "status": 0,
            "msg": "keepalive failed!reason:token invalid"
        })

    # 获得keep_alive_key 更新最新存活时间
    user_online_key = RedisClient.get_user_online_key(record_key)

    # 设置最新存活时间 最多存在五分钟
    redis_cache_client.setex(user_online_key, settings.MAX_LOST_HEART_TIME,
                             int(time.time()))

    return success({
        "status": 1,
        "msg": "keepalive success",
        "data": WindowsService.get_current_time_charging(charging)
    })
Example #6
0
def get_device_game_state():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    device_code = request.json.get('device_code')
    if not isinstance(device_code, basestring):
        return fail(HTTP_OK, u"参数类型错误!")

    update_state = DeviceService.get_update_state(device_code)
    if update_state is None:
        log.error("当前设备号没有获取到任何设备信息: {}".format(device_code))
        return fail(HTTP_OK, u'当前设备号信息不正确,无法获取更新状态信息')

    return success(update_state)
Example #7
0
def delete_devices():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    id_list = request.json.get('list', None)
    if not isinstance(id_list, list):
        log.warn("参数错误: id_list = {}".format(id_list))
        return fail(HTTP_OK, u"传入不是id列表")

    result_list = []
    for device_id in id_list:
        if not DeviceService.delete_device(device_id):
            log.warn("当前设备删除失败: device_id = {}".format(device_id))
            continue

        result_list.append(device_id)
    return success(result_list)
Example #8
0
def device_game_list():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    device_code = request.json.get('device_code')
    device = DeviceService.get_device_by_code(device_code)
    if device is None:
        log.error("当前设备号没有获取到任何设备信息: {}".format(device_code))
        return fail(HTTP_OK, u"参数错误!!")

    # if not isinstance(page, int) or \
    #         not isinstance(size, int):
    #     log.error("获取游戏列表参数错误: page = {} size = {} device_code = {}".format(
    #         page, size, device_code))
    #     return fail(HTTP_OK, u"参数错误!!")
    #
    # if page <= 0 or size <= 0:
    #     log.error("获取游戏列表参数错误, 不能小于0: page = {} size = {} device_code = {}".format(
    #         page, size, device_code))
    #     return fail(HTTP_OK, u"参数错误!!")

    return DeviceGameService.get_device_game_list(device.id)
Example #9
0
def check_connect():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    device_code = request.json.get('device_code')
    if device_code is None:
        return fail(HTTP_OK, u"not have device_code!!!")

    # 获得设备使用状态
    device_status = DeviceService.get_device_status(device_code)
    if device_status is None:
        return success({
            'status': -1,
            'device_status': device_status,
            'msg': "not deploy"
        })

    # 保持心跳
    DeviceService.keep_device_heart(device_code)

    # 从维护状态跳转到空闲状态
    if device_status == DeviceStatus.STATUS_MAINTAIN:
        log.info("当前状态为维护状态,设备已经有心跳需要重新设置空闲状态!")
        DeviceService.status_transfer(device_code, device_status,
                                      DeviceStatus.STATUE_FREE)

        # 重新获得设备状态
        device_status = DeviceService.get_device_status(device_code)

    device_code_key = RedisClient.get_device_code_key(device_code)
    record_key = redis_cache_client.get(device_code_key)
    if record_key is None:
        return success({
            'status': 0,
            'device_status': device_status,
            'msg': "not login"
        })

    return success({
        "status": 1,
        "token": record_key,
        'device_status': device_status,
        "msg": "login successed!"
    })
Example #10
0
def deploy_device():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    # json = {
    #     'province': 'xxx',
    #     'city': 'xxxx',
    #     'area': 'xxxx',
    #     'location': 'xxx',
    #     'device_code': 'xxxx',
    # }

    province = request.json.get('province', None)
    city = request.json.get('city', None)
    area = request.json.get('area', None)
    location = request.json.get('location', None)
    if province is None or city is None \
            or area is None or location is None \
            or province == '' or city == '' \
            or area == '' or location == '':
        log.warn(
            "地址信息传入错误: province = {} city = {} area = {} location = {}".format(
                province, city, area, location))
        return fail(HTTP_OK, u"地址信息传入错误!")

    # 获得设备编号信息
    device_code = request.json.get('device_code', None)
    if device_code is None:
        log.warn("没有设备编号信息无法部署...")
        return fail(HTTP_OK, u"没有设备编号信息无法部署!")

    charge_id = request.json.get('charge_id', None)
    if charge_id is None:
        log.warn("当前部署没有传入费率模板ID: device_code = {}".format(device_code))
        return fail(HTTP_OK, u"没有传入费率模板ID")

    charge = Charge.get(charge_id)
    if charge is None:
        log.warn("当前费率模板不存在: charge_id = {} device_code = {}".format(
            charge_id, device_code))
        return fail(HTTP_OK, u"当前费率模板不存在!")

    # 先获得地址信息 通过地址四个属性进行查找
    address = Address.find_address(province, city, area, location)
    if address is None:
        # 如果地址信息不存在则创建地址但是设备数要先初始化为0
        address, is_success = Address.create(province,
                                             city,
                                             area,
                                             location,
                                             device_num=0)
        if address is None:
            log.warn(
                "部署设备时地址信息创建失败了: province = {} city = {} area = {} location = {} device_code = {}"
                .format(province, city, area, location, device_code))
            return fail(HTTP_OK, u"新建地址信息失败了!")

    # 先判断设备是否已经存在设备列表中
    device = DeviceService.get_device_by_code(device_code)
    if device is None:
        # 如果没有找到设备信息则新建设备信息
        device, is_success = DeviceService.create(device_code, address.id,
                                                  charge_id)
        if device is None:
            log.warn("新建设备信息失败了!!")
            return fail(HTTP_OK, u"新建设备信息失败了!")
        if not address.add_device_num(1):
            log.warn("新增设备数目存储失败!!")
            return fail(HTTP_OK, u"新增设备数目存储失败!")

        # 部署游戏信息
        DeviceGameService.deploy_device_game(device)

        # 这里添加部署记录然后返回
        deploy, is_success = Deploy.create(device.id, province, city, area,
                                           location)
        if deploy is None:
            log.warn("添加部署记录失败!")
            return fail(HTTP_OK, u"添加部署记录失败!")

        log.info(
            "添加部署记录成功: province = {} city = {} area = {} location = {} device_code = {}"
            .format(province, city, area, location, device_code))
        return success(deploy.to_dict())

    # 添加部署记录 先判断当前部署的位置是否和设备当前所处的位置是一样的
    if device.address_id == address.id:
        log.info(
            "当前设备部署的位置没有发生任何变化,不需要记录: device.id = {} address.id = {}".format(
                device.id, address.id))
        return success(u"当前设备部署位置没有发生任何变化,不需要增加部署记录")

    # 先获得之前部署的位置
    address_old = Address.get(device.address_id)
    if address_old.device_num > 0:
        if not address_old.add_device_num(-1):
            return fail(HTTP_OK, u"减少设备数目存储失败!")

    # 然后更改部署的位置
    device.address_id = address.id
    if not address.add_device_num(1):
        log.warn("新增设备数目存储失败!!")
        return fail(HTTP_OK, u"新增设备数目存储失败!")

    # 增加部署记录
    deploy, is_success = Deploy.create(device.id, province, city, area,
                                       location)
    if deploy is None:
        log.warn("添加部署记录失败!")
        return fail(HTTP_OK, u"添加部署记录失败!")

    log.info(
        "添加部署记录成功: province = {} city = {} area = {} location = {} device_code = {}"
        .format(province, city, area, location, device_code))
    return success(deploy.to_dict())
Example #11
0
def modify_device_game_state():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    device_code = request.json.get('device_code')
    update_state = request.json.get('update_state')

    if update_state not in (DeviceUpdateStatus.UPDATE_ING,
                            DeviceUpdateStatus.UPDATE_FINISH):
        log.error("当前状态不允许: update_state = {}".format(update_state))
        return fail(HTTP_OK, u"参数错误!")

    device = DeviceService.get_device_by_code(device_code)
    if device is None:
        log.error("当前设备号没有获取到任何设备信息: {}".format(device_code))
        return fail(HTTP_OK, u"参数错误,获取设备信息失败!!")

    # 获取当前游戏更新状态
    current_update_state = DeviceService.get_update_state(device)

    # 获取当前设备状态
    current_status = DeviceService.get_device_status(device)

    # 如果当前发送过来的状态是ing 则设备当前游戏更新状态必须是ing,否则状态错误
    if update_state == DeviceUpdateStatus.UPDATE_ING:
        if current_update_state == DeviceUpdateStatus.UPDATE_CHECK:
            return fail(HTTP_OK, u"当前游戏更新状态错误, 自检中不接收ing状态")

        # 锁定设备
        if current_status != DeviceStatus.STATUE_FREE and \
                        current_status != DeviceStatus.STATUE_LOCK:
            return fail(HTTP_OK, u"当前设备不为空闲或者锁定状态,无法更新!")

        # 如果当前设备为空闲状态 则锁定设备
        if current_status == DeviceStatus.STATUE_FREE:
            if not DeviceService.set_device_status(device,
                                                   DeviceStatus.STATUE_LOCK):
                log.error("锁定设备失败,设置设备状态信息失败: device_id = {}".format(
                    device.id))
                return fail(HTTP_OK, u'锁定设备失败,设置设备状态信息失败!!')

        if DeviceService.set_update_state(device, update_state):
            return success(u"设备游戏更新状态设置成功!")
        return fail(HTTP_OK, u"更新状态设置失败")

    # 判断当前属于什么状态
    if current_update_state == DeviceUpdateStatus.UPDATE_FINISH:
        return success(u'当前属于游戏更新完成状态,不需要设置')

    # 如果当前设备被锁定了 则解锁
    if current_status == DeviceStatus.STATUE_LOCK:
        if not DeviceService.set_device_status(device,
                                               DeviceStatus.STATUE_FREE):
            log.error("解锁设备异常: device_id = {}".format(device.id))
            return fail(HTTP_OK, u'设备解锁失败,多进程写入设备状态异常!')

    # 如果当前属于更新中状态
    if current_update_state == DeviceUpdateStatus.UPDATE_ING:
        # 设置游戏更新完成。。
        DeviceGameService.update_device_game(device_id=device.id)
        if DeviceService.set_update_state(device,
                                          update_state,
                                          last_update_time=datetime.now()):
            return success(u"设备游戏更新状态设置成功!")
        return fail(HTTP_OK, u"更新状态设置失败")

    if DeviceService.set_update_state(device, update_state):
        return success(u"设备游戏更新状态设置成功!")
    return fail(HTTP_OK, u"更新状态设置失败")
Example #12
0
def qr_code_online(device_code):
    # # 当前用户没有登录
    # LOGIN_ERROR_BIND = -1
    # # 当前用户已经被删除
    # LOGIN_ERROR_DELETE = -2
    # # 当前用户被禁止使用
    # LOGIN_ERROR_FORBID = -3
    # # 当前设备不存在
    # LOGIN_ERROR_NOT_FIND = -4
    # # 用户余额不足
    # LOGIN_ERROR_NOT_SUFFICIENT_FUNDS = -5
    # # 上机失败 未知错误
    # LOGIN_ERROR_UNKNOW = -6
    # # 设备已经在使用了
    # LOGIN_ERROR_DEVICE_IN_USEING = -7
    # # 当前用户已经在使用上机了,但是不是当前设备在使用
    # LOGIN_ERROR_USER_IN_USEING = -8
    # # 当前设备不处于空闲状态,不能上机
    # LOGIN_ERROR_DEVICE_NOT_FREE = -9

    scan_from = request.args.get('from')
    # 登录链接
    login_url = url_for("wechat.menu", name="login")
    # 通过微信二维码扫描则需要判断当前用户是否已经关注公众号
    if scan_from != 'playing':
        # # 初始化用户关注信息
        # subscribe, nick_name, head_img_url = 0, '', ''

        openid = session.get('openid', None)
        # 如果不是微信二维码扫描 则跳转到登录界面
        if openid is None:
            log.info("当前扫描登录没有openid,需要跳转到登录界面..")
            return redirect(login_url)

        # 获得用户的关注状态 以及头像和昵称信息
        subscribe, nick_name, head_img_url = get_wechat_user_info(openid)
        # 如果用户没有关注微信号 直接跳转到关注页面
        if subscribe != 1:
            log.info("当前用户没有关注公众号: subscribe = {} openid = {}".format(
                subscribe, openid))
            return redirect(ATTENTION_URL)

        # 如果当前用户已经关注 则直接跳转到 祥基指定的链接 2017-10-13 15:26:00
        url = '#/playing?code={}'.format(device_code)
        log.info("当前用户已经关注了公众号,跳转链接: {}".format(url))
        return redirect(url)

    user_id_cookie = session.get('u_id')
    if user_id_cookie is None:
        log.warn("当前session中没有u_id 信息,需要登录...")
        return fail(HTTP_OK, u'当前用户没有登录', LOGIN_ERROR_BIND)

    user_id = decode_user_id(user_id_cookie)
    if user_id is None:
        log.warn(
            "当前用户信息被篡改,需要重新登录: user_id_cookie = {}".format(user_id_cookie))
        return fail(HTTP_OK, u'当前用户登录信息被篡改, 不能登录', LOGIN_ERROR_BIND)

    # 获得用户信息
    user = get_current_user(user_id)
    if user is None:
        log.warn("当前user_id还未绑定手机号码: user_id = {}".format(user_id))
        return fail(HTTP_OK, u"用户还绑定手机号码登录!", LOGIN_ERROR_BIND)

    # 如果当前用户 被禁用 则不能上机
    if user.deleted:
        log.warn("当前用户已经被删除了,无法上机: user_id = {}".format(user.id))
        return fail(HTTP_OK, u"当前用户已经被删除了,不能上机", LOGIN_ERROR_DELETE)

    # 判断当前用户是否已经被禁用了
    if user.state == 'unused':
        log.warn("当前用户已经被禁用了,无法上机: user_id = {}".format(user.id))
        return fail(HTTP_OK, u"当前用户已经被禁用了,不能上机", LOGIN_ERROR_FORBID)

    # 获得设备信息
    device = DeviceService.get_device_by_code(device_code=device_code)
    if device is None:
        log.warn("当前设备号没有对应的设备信息: device_code = {}".format(device_code))
        return fail(HTTP_OK, u"设备信息异常,设备不存在", LOGIN_ERROR_NOT_FIND)

    # 获得最新费率
    charge_mode = DeviceService.get_charge_mode(device)
    log.info("当前费率: charge_mode = {}".format(charge_mode))

    # 判断用户是否余额充足 如果小于一分钟不能上机
    if user.balance_account < charge_mode:
        log.info(
            "用户余额不足,不能上机: user_id = {} device_id = {} account = {}".format(
                user.id, device.id, user.balance_account))
        return fail(HTTP_OK, u"用户余额不足,不能上机!", LOGIN_ERROR_NOT_SUFFICIENT_FUNDS)

    # 判断是否已经在redis中进行记录
    record_key = RedisClient.get_record_key(user.id, device.id)
    # 获得用户上机key
    user_key = RedisClient.get_user_key(user.id)
    # 获得设备上机key
    device_key = RedisClient.get_device_key(device.id)

    # 判断是否已经登录了
    charging = redis_cache_client.get(record_key)
    if charging is None:

        # 判断当前设备是否已经在使用了
        if redis_cache_client.get(device_key):
            log.warn("当前设备{}已经在被使用,但是用户ID = {}又在申请".format(device.id, user.id))
            return fail(HTTP_OK, u"当前设备已经在使用上机了,但是不是当前用户在使用!",
                        LOGIN_ERROR_DEVICE_IN_USING)

        # 判断当前用户是否已经上机了
        if redis_cache_client.get(user_key):
            log.warn("当前用户{}已经在上机,但是又在申请当前设备ID = {}".format(
                user.id, device.id))
            return fail(HTTP_OK, u"当前用户已经在使用上机了,但是不是当前设备在使用!",
                        LOGIN_ERROR_USER_IN_USING)

        # 判断当前设备是否处于空闲状态 且设备必须处于在线状态
        device_status = DeviceService.get_device_status(device)
        device_alive = DeviceService.get_device_alive_status(device)
        if device_status != DeviceStatus.STATUE_FREE or device_alive != Device.ALIVE_ONLINE:
            log.warn("当前设备不处于空闲状态,不能上机: device_id = {} state = {} alive = {}".
                     format(device.id, device_status, device_alive))
            return fail(HTTP_OK, u"当前设备不处于空闲状态,或者当前设备不在线,不能上机!",
                        LOGIN_ERROR_DEVICE_NOT_FREE)

        # 判断当前设备是否正在更新 或者正在自检,这种状态下不能够登录上机
        current_update_state = DeviceService.get_update_state(device)
        if current_update_state == DeviceUpdateStatus.UPDATE_ING or \
                        current_update_state == DeviceUpdateStatus.UPDATE_CHECK:
            log.info(
                "当前设备正在更新或者自检中,不能登录: device_id = {} current_update_state = {}".
                format(device.id, current_update_state))
            return fail(HTTP_OK, u"当前设备处于自检或者更新中,不能上机!",
                        LOGIN_ERROR_DEVICE_NOT_FREE)

        log.info("用户还未上机可以进行上机: user_id = {} device_id = {}".format(
            user.id, device.id))
        if not WindowsService.do_online(user, device, charge_mode):
            log.warn("上机记录创建失败,上机失败: user_id = {} device_id = {}".format(
                user.id, device.id))
            return fail(HTTP_OK, u"上机异常!!", LOGIN_ERROR_UNKNOW)

    log.info("来自微信端游戏仓界面扫描: user_id = {} device_id = {}".format(
        user.id, device.id))
    return success()
Example #13
0
def maintain_login():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    device_code = request.json.get('device_code')
    username = request.json.get('username')
    password = request.json.get('password')

    if device_code is None or username is None or password is None:
        log.error(
            "参数错误,无法登录维修账号: device_code = {} username = {} password = {}".
            format(device_code, username, password))
        return fail(HTTP_OK, u"参数错误!!")

    # 判断维修人员用户密码是否正确
    maintain = MaintainService.get_maintain_by_username(username)
    if maintain is None:
        log.error("当前维修人员账号不存在: username = {} password = {}".format(
            username, password))
        return fail(HTTP_OK, u"当前维修人员账号不存在,维修人员无法登录!!")

    # 判断当前用户是否已经被禁用了
    if maintain.state == Maintain.STATUS_FORBID:
        return fail(HTTP_OK, u"当前账户已被禁用,无法登录!!")

    # 判断密码是否正确
    if not maintain.verify_password(password):
        log.error("当前维护人员密码错误: username = {} password = {}".format(
            username, password))
        return fail(HTTP_OK, u"密码错误,维修人员无法登录!!")

    # 判断当前设备信息是否存在
    device = DeviceService.get_device_by_code(device_code)
    if device is None:
        log.error("当前设备号没有设备信息: device_code = {}".format(device_code))
        return fail(HTTP_OK, u"当前设备号没有设备信息!!")

    # 判断当前设备存活状态
    if DeviceService.get_device_alive_status(device) == Device.ALIVE_OFFLINE:
        log.error("当前设备离线,维修人员无法登录: device_code = {}".format(device_code))
        return fail(HTTP_OK, u"当前设备离线,维修人员无法登录!!")

    # 判断当前设备使用状态
    if DeviceService.get_device_status(device) == DeviceStatus.STATUE_BUSY:
        log.error("当前设备用户正在使用,维修人员无法登录: device_code = {}".format(device_code))
        return fail(HTTP_OK, u"当前设备用户正在使用,维修人员无法登录!!")

    # 判断当前维护人员账号能否登录当前地址
    if maintain.address_id != Maintain.ALL_ADDRESS_ID:
        address = Address.get(maintain.address_id)
        if address is None:
            log.error("当前维护人员管理的地址信息不存在,无法登录")
            return fail(HTTP_OK, u"当前维护人员管理的地址信息不存在,无法登录!")
        device_address = device.address.get_full_address()
        maintain_address = address.get_full_address()
        if device_address != maintain_address:
            log.error(
                "当前维护人员管理的地址与设备所在地址不一致,无法登录: maintain_id = {} device_id = {}"
                " device_address = {} maintain_address = {}".format(
                    maintain.id, device.id, device_address, maintain_address))
            return fail(HTTP_OK, u"当前维护人员管理的地址与设备所在地址不一致,无法登录!")

    # 开始登录,先设置设备状态
    if not DeviceService.set_device_status(device,
                                           DeviceStatus.STATUS_MAINTAIN):
        log.error(
            "设备状态切换错误, 维修人员无法登录: device_code = {} username = {} password = {}".
            format(device_code, username, password))
        return fail(HTTP_OK, u"设备状态切换异常, 维修人员无法登录!")

    log.info("维修人员登录设备成功: device_code = {} username = {} password = {}".format(
        device_code, username, password))
    return success(u"登录成功")
Example #14
0
def lock_device():
    if not request.is_json:
        log.warn("参数错误...")
        return fail(HTTP_OK, u"need application/json!!")

    device_id = request.json.get('id')
    lock = request.json.get('lock')

    if device_id is None or lock is None:
        log.error("传入参数不正确: id = {} lock = {}".format(device_id, lock))
        return fail(HTTP_OK, u"传入参数错误!")

    # 获得设备信息
    device = DeviceService.get_device_by_id(device_id)
    if device is None:
        log.error("当前设备ID没有找到设备信息: device_id = {}".format(device_id))
        return fail(HTTP_OK, u"当前设备ID没有找到设备信息!")

    # 获取当前设备存活状态
    alive = DeviceService.get_device_alive_status(device)
    if alive == Device.ALIVE_OFFLINE:
        log.info("当前设备不在线,无法锁定设备: device_id = {} alive = {}".format(
            device_id, alive))
        return fail(HTTP_OK, u"当前设备不在线,无法锁定设备!")

    # 获取设备当前使用状态
    use_status = DeviceService.get_device_status(device)
    if use_status is None:
        log.error("获取当前设备状态错误, 无法操作设备: device_id = {}".format(device_id))
        return fail(HTTP_OK, u'获取当前设备状态错误, 无法操作设备')

    # 当前是否是想解锁设备
    if not lock:
        if use_status == DeviceStatus.STATUE_LOCK:
            if not DeviceService.set_device_status(device,
                                                   DeviceStatus.STATUE_FREE):
                return fail(HTTP_OK, u'设备解锁失败,多进程写入设备状态异常!')
            log.info("解锁设备成功: device_id = {} device_code = {}".format(
                device.id, device.device_code))
            return success(u'解锁设备成功')
        return success(u'当前设备未锁定,不需要解锁!')

    # 判断设备是否处于维护状态
    if use_status == DeviceStatus.STATUS_MAINTAIN:
        log.info("当前设备维护人员已登录,无法锁定设备: device_id = {} use_status = {}".format(
            device_id, use_status))
        return fail(HTTP_OK, u"当前设备维护人员已登录,无法锁定设备!")

    if use_status == DeviceStatus.STATUE_LOCK:
        log.info("当前设备已被锁定,不需要再锁定: device_id = {} use_status = {}".format(
            device_id, use_status))
        return success(u"当前设备已被锁定,不需要再锁定")

    # 当前设备处于忙碌状态,锁定设备
    if use_status == DeviceStatus.STATUE_BUSY:
        # log.info("当前设备有用户在使用,强制用户下机,锁定设备: device_id = {} use_status = {}".format(device_id, use_status))
        # if not WindowsService.do_offline_order_by_device_code(device.device_code):
        #     return fail(HTTP_OK, u"强制用户下机失败,无法锁定设备!")
        #
        # if not DeviceService.set_device_status(device, DeviceStatus.STATUE_LOCK):
        #     log.error("锁定设备失败,设置设备状态信息失败: device_id = {}".format(device_id))
        #     return fail(HTTP_OK, u'锁定设备失败,设置设备状态信息失败!!')
        # log.info("锁定设备成功: device_id = {} device_code = {}".format(device.id, device.device_code))
        # return success(u'当前设备有用户在使用,强制用户下机,锁定设备成功')
        return fail(HTTP_OK, u"当前设备用户正在使用,不能锁定!")

    if not DeviceService.set_device_status(device, DeviceStatus.STATUE_LOCK):
        log.error("锁定设备失败,设置设备状态信息失败: device_id = {}".format(device_id))
        return fail(HTTP_OK, u'锁定设备失败,设置设备状态信息失败!!')
    log.info("锁定设备成功: device_id = {} device_code = {}".format(
        device.id, device.device_code))
    return success(u'锁定设备成功')
Example #15
0
    def cal_offline(user_id, device_id, record_id, charge_mode):
        try:
            # 获得用户信息
            user = User.get(user_id)

            # 获得设备信息
            device = DeviceService.get_device_by_id(device_id)

            # 获得试用记录
            record = UseRecord.get(record_id)

            # 记录下机时间
            record.end_time = datetime.now()

            # 设置设备自检, 如果设备处于完成更新状态 则可以进入自检,否则其他状态不能设置自检
            if DeviceService.get_update_state(
                    device) == DeviceUpdateStatus.UPDATE_FINISH:
                if not DeviceService.set_update_state(
                        device, DeviceUpdateStatus.UPDATE_CHECK):
                    log.error("设置自检状态失败: device_code = {}".format(
                        device.device_code))
                    return False, None, None

                log.info("设置自检状态成功: device_code = {}".format(
                    device.device_code))

                # 如果自检状态设备成功,则直接锁定设备
                if not DeviceService.set_device_status(
                        device, DeviceStatus.STATUE_LOCK):
                    log.error("设备自检状态设置成功,锁定设备失败:  device_id = {}".format(
                        device.id))
                    return False, None, None
                log.info("设备自检状态设置成功,锁定设备成功:  device_id = {}".format(
                    device.id))
            else:
                # 设置设备为空闲状态
                if not DeviceService.set_device_status(
                        device, DeviceStatus.STATUE_FREE):
                    log.error("设置设备状态异常,下机失败!")
                    return False, None, None

            log.info("本次上机时间: {} 下机时间: {} 使用记录ID: {} 当前设备: {}".format(
                record.ctime.strftime('%Y-%m-%d %H:%M:%S'),
                record.end_time.strftime('%Y-%m-%d %H:%M:%S'), record_id,
                device.device_code))

            # 计算花费时间
            seconds = (record.end_time - record.ctime).seconds
            # # 如果大于半分钟就以一分钟的价格扣钱
            # if 30 <= seconds < 60:
            #     seconds = 60

            # 计算下机时长
            record.cost_time = cal_cost_time(seconds)
            log.info(
                "本次上机花费的时间: user_id = {} device_id = {} cost_time = {}".format(
                    user_id, device_id, record.cost_time))

            # 计算花费金钱
            record.cost_money = record.cost_time * charge_mode
            log.info("本次上机花费的金钱: user_id = {} device_id = {} cost_money = {}".
                     format(user_id, device_id, record.cost_money))

            # 计算设备获得的金钱数目
            device.income += record.cost_money

            # 计算用户花费的钱
            user.balance_account -= record.cost_money
            if user.balance_account < 0:
                user.balance_account = 0
            log.info("上机后用户所剩余额: user_id = {} balance_account = {}".format(
                user_id, user.balance_account))
            user.used_account += record.cost_money
            user.total_cost_time += record.cost_time

            # 更新各属性时间
            user.utime = datetime.now()
            device.utime = datetime.now()
            record.utime = datetime.now()

            log.info("当前用户总的上机时长: user_id = {} total_cost_time = {}".format(
                user_id, user.total_cost_time))
            db.session.add(user)
            db.session.add(device)
            db.session.add(record)
            db.session.commit()

            return True, record, user
        except Exception as e:
            log.error(
                "未知错误: user_id = {} device_id = {} record_id = {}".format(
                    user_id, device_id, record_id))
            log.exception(e)
            db.session.rollback()

        return False, None, None
Example #16
0
    def do_online(user, device, charge_mode):
        log.info("用户还未上机可以进行上机: user_id = {} device_id = {}".format(
            user.id, device.id))
        record, is_success = UseRecord.create(user.id, device.id,
                                              device.address.province,
                                              device.address.city,
                                              device.address.area,
                                              device.address.location)
        if not is_success:
            return False

        # 判断是否已经在redis中进行记录
        record_key = RedisClient.get_record_key(user.id, device.id)
        # 获得用户上线key
        user_key = RedisClient.get_user_key(user.id)
        # 获得设备上线key
        device_key = RedisClient.get_device_key(device.id)
        # 获得当前设备token
        device_code_key = RedisClient.get_device_code_key(device.device_code)

        # 获得keep_alive_key 更新最新存活时间
        user_online_key = RedisClient.get_user_online_key(record_key)

        log.info(
            "当前上机时间: user_id:{} device_id:{} record_id:{} ctime:{}".format(
                user.id, device.id, record.id,
                record.ctime.strftime('%Y-%m-%d %H:%M:%S')))

        # 获得计费结构体
        charging = record.to_charging()
        # 得到计费方式
        charging['charge_mode'] = charge_mode
        # 得到当前用户总额
        charging['balance_account'] = user.balance_account
        # 填充设备机器码
        charging['device_code'] = device.device_code
        # 填充用户的openid
        charging['openid'] = user.openid

        # charging = {
        #     'id': self.id,
        #     'user_id': self.user_id,
        #     'device_id': self.device_id,
        #     # 花费金额数目
        #     'cost_money': self.cost_money,
        #     # 上机时间
        #     'ctime': self.ctime.strftime('%Y-%m-%d %H:%M:%S'),
        #     # 更新时间,主要用户同步计费
        #     'utime': self.utime.strftime('%Y-%m-%d %H:%M:%S'),
        #     # 已经上机时间
        #     'cost_time': self.cost_time,
        #     # 计费方式 目前默认 5分钱/分钟
        #     'charge_mode': 5,
        #     # 当前用户余额
        #     'balance_account': 10000,
        #     # 设备机器码
        #     'device_code': 'xx-xx-xx-xx-xx-xx',
        # }

        charge_str = json.dumps(charging)

        # 操作redis 需要加锁
        lock = DistributeLock(user_key, redis_cache_client)
        try:
            lock.acquire()

            # 设置设备当前使用状态
            if not DeviceService.set_device_status(device,
                                                   DeviceStatus.STATUE_BUSY):
                log.error("设置设备状态失败, 上机异常!!!")
                return False

            # 开始上线 把上线信息存储redis
            redis_cache_client.set(record_key, charge_str)
            redis_cache_client.set(user_key, record_key)
            redis_cache_client.set(device_key, record_key)
            # 根据设备机器码获得记录token
            redis_cache_client.set(device_code_key, record_key)
            # 设置最新存活时间 最多存活五分钟
            import time
            redis_cache_client.setex(user_online_key,
                                     settings.MAX_LOST_HEART_TIME,
                                     int(time.time()))

            is_success = True
        except Exception as e:
            is_success = False
            log.exception(e)
        finally:
            lock.release()

        # 判断上线是否成功
        if is_success:
            # 发送上线通知
            TemplateService.online(user.openid, record.ctime, device.address,
                                   user.balance_account, charge_mode)

        return True