def _list(): if d['mchnt_id']: where['userid'] = d['mchnt_id'] else: userids = _get_userids() if d.get('groupid'): userid_cache_list = userid_cache[d['groupid']] userids = userids & set(userid_cache_list) if not userids: return self.write(success({'list': [], 'num':0})) where['userid'] = ('in', userids) prts = self.db.select('member_actv', fields=fields, where=where, other='order by ctime desc limit %s offset %s' % (d['limit'], d['offset'])) or [] userids = set([i['userid'] for i in prts]) users = self._get_users(userids) ids = [] for prt in prts: user = users.get(prt['userid'], {}) prt['shopname'] = user.get('shopname') or '' prt['addr'] = user.get('addr') or '' prt['bg_url'] = prt['bg_url'] or config.MCHNT_AVATAR prt['start_time'] = str_to_tstamp(str(prt['start_time'])) prt['expire_time'] = str_to_tstamp(str(prt['expire_time'])) ids.append(prt['id']) MemberUtil.add_actv_pv(ids) # 获取总量 num = self.db.select_one('member_actv', where=where, fields='count(1) as num')['num'] return self.write(success({'list': prts, 'num': num}))
def card_list(self, d): with get_connection_exception('qf_mchnt') as db: where = { 'mp.customer_id': d['customer_id'], 'ca.expire_time': ('>', int(time.time())) } if d.get('groupid') and not userid_cache[d['groupid']]: return [], 0 if d['mchnt_id']: link_ids = apcli.userids_by_linkid(int(d['mchnt_id']), 'merchant') or [] link_ids = {i.userid for i in link_ids} link_ids.add(d['mchnt_id']) where['ca.userid'] = ('in', link_ids) elif d.get('groupid') and userid_cache[d['groupid']]: where['ca.userid'] = ('in', userid_cache[d['groupid']]) on = {'mp.activity_id': 'ca.id'} fields = ['mp.' + i for i in ('cur_pt', 'id', 'activity_id')] fields += [ 'ca.' + i for i in ('obtain_amt', 'obtain_limit', 'start_time', 'expire_time', 'exchange_pt', 'goods_amt', 'goods_name', 'status', 'userid') ] r = db.select_join('member_pt mp', 'card_actv ca', on=on, where=where, fields=fields, other=('order by mp.cur_pt desc ' 'limit {} offset {}'.format( d['limit'], d['offset']))) or [] total_num = db.select_join_one('member_pt mp', 'card_actv ca', on=on, where=where, fields='count(1) as num')['num'] if not r: return r, total_num # 用户信息 userids = [i['userid'] for i in r] users = apcli_ex('findUserBriefsByIds', userids) users = {i.uid: i.__dict__ for i in users} for i in r: t = users.get(i['userid']) or {} i['id'] = str(i['id']) i['activity_id'] = str(i['activity_id']) i['shopname'] = t.get('shopname') or '' i['addr'] = t.get('address') or '' i['diff_exchange'] = max( i['exchange_pt'] - i['cur_pt'] % i['exchange_pt'], 0) i['exchange'] = i['cur_pt'] / i['exchange_pt'] i['start_time'] = str_to_tstamp(str(i['start_time'])) i['expire_time'] = str_to_tstamp(str(i['expire_time'])) return r, total_num
def POST(self): userid = int(self.user.userid) # 商户付费状态 groupid = self.get_groupid() mchnt = get_payinfo_ex(userid, service_code='card_actv', groupid=groupid) if not mchnt: add_free_ex(userid, service_code='card_actv', groupid=groupid) elif str(mchnt['expire_time']) <= time.strftime(DATETIME_FMT): if mchnt['status'] == MCHNT_STATUS_FREE: raise ParamError('免费体验已经到期了哦') if mchnt['status'] == MCHNT_STATUS_NORMAL: raise ParamError('付费已经到期了哦') # 能否创建集点活动 self.allow_create(userid) actv = self.validator.data # 适用门店 d = self.req.input() actv['mchnt_id_list'] = self.get_mchnt_id_list( d.get('mchnt_id_list', '').strip().split(',')) actv['userid'] = userid actv['goods_name'] = remove_emoji(actv.get('goods_name')) if not 1 <= str_len(actv['goods_name']) <= 8: raise ParamError('商品名长度是1至8位') if actv['goods_amt'] <= 0: raise ParamError('商品价格应大于0') actv['start_time'] = actv.get('start_time') or time.strftime(DT_FMT) if not(is_valid_date(actv['start_time']) and is_valid_date(actv['expire_time'])): raise ParamError('活动时间格式不合法') if actv['start_time'] > actv['expire_time']: raise ParamError('开始时间应该小于结束时间') actv['start_time'] = str_to_tstamp(actv['start_time'], DT_FMT) actv['expire_time'] = str_to_tstamp(actv['expire_time'], DT_FMT) + 86399 if actv['exchange_pt'] not in range(1, 11): raise ParamError('暂不只支持该兑换集点的活动') if actv['obtain_amt'] <= 0: raise ParamError('集点条件大于0') if actv['obtain_limit'] < 0: raise ParamError('一次交易获取的最多集点应该大于0') actv['id'] = getid() actv['ctime'] = actv['utime'] = int(time.time()) actv['status'] = ACTV_STATUS_NORMAL with get_connection_exception('qf_mchnt') as db: db.insert('card_actv', actv) return self.write(success({'id': actv['id']}))
def param(): td = time.strftime(DATETIME_FMT) update_userids = {i['userid'] for i in mchnts} insert_userids = list(set(d['userid']) - update_userids) outdate_userids = { i['userid'] for i in mchnts if str(i['expire_time']) < td } indate_userids = { i['userid'] for i in mchnts if str(i['expire_time']) > td } # 默认免费体验时间 free = 0 for services in (old_services, new_services): if d['goods_code'] in services: free = services[d['goods_code']] break st = datetime.date.today() expire_time = str_to_tstamp( str( future( st, years=d['year'], months=d['month'], days=d['day'])) + ' 23:59:59', DATETIME_FMT) _insert(insert_userids, expire_time + free * 24 * 3600) # 更新会员(已过期) _update(outdate_userids, expire_time=expire_time) # 更新会员(未过期) exp = (d['year'] * 365 + d['month'] * 30 + d['day']) * 24 * 3600 expire_time = DBFunc('expire_time+%d' % exp) _update(indate_userids, expire_time=expire_time)
def _trans_input(self): d = {k: v.strip() for k, v in self.req.input().iteritems()} r = {} r['id'] = d.get('id') or '' # actv info with get_connection_exception('qf_mchnt') as db: info = db.select_one('card_actv', where={'id': r['id']}) if not info: raise ParamError('活动不存在') info['start_time'] = int(time.mktime(info['start_time'].timetuple())) expire_time = d.get('expire_time', info['expire_time']) if not is_valid_date(expire_time): raise ParamError('活动截止时间格式不对') r['expire_time'] = str_to_tstamp(expire_time, DATE_FMT) + 86399 #if r['expire_time'] < info['start_time']: #raise ParamError('修改活动的截止日期不能小于起始日期') r['obtain_amt'] = int(d.get('obtain_amt', info['obtain_amt']) or 0) if r['obtain_amt'] <= 0: raise ParamError('集点条件大于0元') r['goods_name'] = remove_emoji(d.get('goods_name', info['goods_name'])) if not 1 <= str_len(r['goods_name']) <= 8: raise ParamError('商品名长度是1至8位') r['goods_amt'] = int(d.get('goods_amt', info['goods_amt']) or 0) if r['goods_amt'] <= 0: raise ParamError('商品价格应大于0') r['content'] = (info['content'] or '') + (d.get('content') or '%smis修改' % (time.strftime(DATETIME_FMT))) return r
def _info(): where = {'expire_time': ('>', now), 'status': 1, 'userid': d['userid']} # 获取详细信息 where['userid'] = d['userid'] r = self.db.select_one('member_actv', where=where, fields=fields, other='order by ctime desc') if r: r['title'] = r['title'] or r['content'] r['content'] = '' if r['title'] == r['content'] else r['content'] r['bg_url'] = r['bg_url'] or config.MCHNT_AVATAR r['start_time'] = str_to_tstamp(str(r['start_time'])) r['expire_time'] = str_to_tstamp(str(r['expire_time'])) MemberUtil.add_actv_pv(r['id']) # 获取过去消费过的店铺 where['userid'] = ('in', _get_userids()) # 获取总量 num = self.db.select_one('member_actv', where=where, fields='count(1) as num')['num'] return self.write(success({'info': r or {}, 'num': num}))
def card_info(self, actv): r = {} # 活动信息 fields = ('goods_name', 'goods_amt', 'exchange_pt', 'obtain_amt', 'obtain_limit', 'status', 'start_time', 'expire_time') for i in fields: r[i] = actv.get(i) or '' r['start_time'] = str_to_tstamp(str(r['start_time']), DATETIME_FMT) r['expire_time'] = str_to_tstamp(str(r['expire_time']), DATETIME_FMT) # 店铺信息 user = apcli_ex('findUserBriefById', actv['userid']) r['shopname'] = getattr(user, 'shopname', '') r['addr'] = getattr(user, 'address', '') return r
def GET(self): customer_id = self.get_cid() aid = int(self.req.input().get('id')) actv = None with get_connection_exception('qf_mchnt') as db: where = {'mp.customer_id': customer_id, 'mp.id': aid} on = {'mp.activity_id': 'ca.id'} fields = [ 'mp.' + i for i in ('cur_pt', 'userid', 'id', 'activity_id') ] fields += [ 'ca.' + i for i in ('obtain_amt', 'start_time', 'expire_time', 'obtain_limit', 'exchange_pt', 'goods_amt', 'goods_name', 'status') ] actv = db.select_join_one('member_pt mp', 'card_actv ca', on=on, where=where, fields=fields) or {} if not actv: raise ParamError('未找到该卡信息') user = apcli_ex('findUserBriefById', actv['userid']) or {} if user: user = user.__dict__ actv['id'] = str(actv['id']) actv['activity_id'] = str(actv['activity_id']) actv['shopname'] = user.get('shopname') or '' actv['addr'] = user.get('address') or '' actv['diff_exchange'] = max( actv['exchange_pt'] - actv['cur_pt'] % actv['exchange_pt'], 0) actv['exchange'] = actv['cur_pt'] / actv['exchange_pt'] actv['start_time'] = str_to_tstamp(str(actv['start_time']), DATETIME_FMT) actv['expire_time'] = str_to_tstamp(str(actv['expire_time']), DATETIME_FMT) actv['is_baipai'] = self.is_baipai(user['groupid']) return self.write(success(actv))
def GET(self): d = self._trans_input() # fields fields = ('cast(id as char) as id, status, title, bg_url,' 'content, start_time, expire_time, audit_info, userid') # where where = {'id': d['id']} # 获取活动报名详细信息 with get_connection_exception('qf_mchnt') as db: r = db.select_one('member_actv', where = where, fields = fields) if not r: raise ParamError('该活动不存在') MemberUtil.add_actv_pv(r['id']) r['state'] = MemberUtil.get_actv_state(r) r['start_time'] = str_to_tstamp(str(r['start_time'])) r['expire_time'] = str_to_tstamp(str(r['expire_time'])) # 店铺信息 shop_info = self._get_user(r['userid']) r['shop_info'] = { 'addr': shop_info['address'], 'mobile': shop_info['mobile'], 'shopname': shop_info['shopname'], } # 消费者信息 member_info = get_member_info(d['customer_id']) or {} r['customer_info'] = { 'nickname': member_info.get('nickname') or '顾客', 'gender': member_info.get('gender') or 3, 'avatar': member_info.get('avatar') or config.HJ_AVATAR } return self.write(success(r))
def _update_v1(): ''' 老版本更新 ''' with get_connection('qf_mchnt') as db: # 获取当前的信息 upwhere = { 'goods_code': order['goods_code'], 'userid': order['userid'] } try: info = db.select_one('recharge', where=upwhere) except: info = None # 更新当前级别的信息 try: price = RechargeUtil.get_price(order['goods_code'], order['price_code']) st = datetime.date.today() if info: exptm = info['expire_time'] if str(exptm) > time.strftime(DATETIME_FMT): st = datetime.date(year=exptm.year, month=exptm.month, day=exptm.day) add_conf = {price['alidity']['unit']: price['alidity']['key']} end = str_to_tstamp( str(future(st, **add_conf)) + ' 23:59:59', DATETIME_FMT) # 若不存在,则直接插入 if info: updata = { 'expire_time': end, 'utime': int(time.time()), 'status': 2 } db.update('recharge', updata, upwhere) else: indata = {} indata['id'] = getid() indata['userid'] = order['userid'] indata['goods_code'] = order['goods_code'] indata['status'] = 2 indata['expire_time'] = end + config.PAYING_GOODS[ 'free'] * 24 * 3600 indata['ctime'] = indata['utime'] = int(time.time()) db.insert('recharge', indata) except: log.warn('更新消费者有效期失败:%s' % traceback.format_exc())
def update_mchnt(self, userid, goods_codes, months): st = datetime.date.today() with get_connection('qf_mchnt') as db: # 获取当前的信息 infos = db.select(table='recharge', where={ 'goods_code': ('in', goods_codes), 'userid': userid }) or [] infos = {i['goods_code']: i for i in infos} for code in goods_codes: try: if code in infos: exptm = infos[code]['expire_time'] if str(exptm) > time.strftime(DATETIME_FMT): st = datetime.date(year=exptm.year, month=exptm.month, day=exptm.day) end = str_to_tstamp( str(future(st, months=months)) + ' 23:59:59', DATETIME_FMT) if code in infos: db.update(table='recharge', values={ 'expire_time': end, 'utime': int(time.time()), 'status': 2 }, where={ 'userid': userid, 'goods_code': code }) else: db.insert(table='recharge', values={ 'id': getid(), 'userid': userid, 'goods_code': code, 'status': 2, 'expire_time': end, 'ctime': int(time.time()), 'utime': int(time.time()), }) except: log.warn('更新消费者有效期失败:%s' % traceback.format_exc())
def _trans_input(self): d = {k: v.strip() for k, v in self.req.input().iteritems()} r = {} # 商户userid r['userid'] = json.loads(d.get('userid') or '') if not r['userid']: raise ParamError('充值商户ID不能为空') # 调整截止日期模式 r['mode'] = d.get('mode', 'dtm') if r['mode'] == 'dtm': # 商户过期时间 expdtm = d.get('expire_time') if not is_valid_datetime(expdtm): raise ParamError('截止日期时间格式不对') r['expire_time'] = str_to_tstamp(expdtm, DATETIME_FMT) elif r['mode'] == 'param': if not all( map(is_valid_int, (d.get('year'), d.get('month'), d.get('day')))): raise ParamError('日期参数必须为整数') r['year'] = int(d.get('year', '0')) r['month'] = int(d.get('month', '0')) r['day'] = int(d.get('day', '0')) if not any((r['year'], r['month'], r['day'])): raise ParamError('延长日期不能为0') # 备注 r['content'] = d.get('content', '') # 商户状态 if d.get('status') in map(str, MCHNT_STATUS): r['status'] = int(d.get('status')) # 会员服务 r['goods_code'] = d.get('goods_code', 'card') return r
def POST(self): info = {'code': '', 'codeDesc': ''} params = self.req.inputjson() banktype = params.get('banktype', '1') if banktype == '1': userid = int(self.user.userid) key = 'verify_account_{}'.format(str(userid)) if redis_pool.exists(key): count = int(redis_pool.get(key)) if count >= config.CHANGE_BANK_LIMIT: info['codeDesc'] = config.CHANGE_LIMIT_TIP return self.write(success(info)) else: redis_pool.incr(key) else: redis_pool.incr(key) start_time_stmp = int(time.time()) end_time = datetime.now().strftime('%Y-%m-%d') + " 23:59:59" end_time_stmp = str_to_tstamp(end_time) expire_time = end_time_stmp - start_time_stmp redis_pool.expire(key, expire_time) bankuser = params.get('bankuser', '') bankaccount = params.get('bankaccount', '') r = apcli.userprofile_by_id(userid) if not r: raise ParamError('获取用户信息失败') else: idCard = r.get('user', {}).get('idnumber', '') result = verify_account(config.PATH, config.APPKEY, userCode="CITI20170912174935", sysCode="CITIAPP20170912175227", bankuser=bankuser, bankaccount=bankaccount, idCard=idCard) return self.write(success(result)) else: return self.write(success(info))
def POST(self): d = self.req.inputjson() actv = self.check_allow_change(d.get('id')) update_value = { 'utime': int(time.time()), 'status': ACTV_STAUS_STOPED, } # 结束申明 if d.get('statement'): statement = remove_emoji(d['statement']) if not 1 <= str_len(statement) <= 150: raise ParamError('停止活动声明应该是1至150位') update_value['statement'] = statement # 结束时间 if d.get('expire_time'): expire_time = d.get('expire_time') if not is_valid_date(expire_time): raise ParamError('截止日期时间格式不对') if expire_time > str(actv['expire_time']): raise ParamError('只能缩短活动截止日期') # 活动结束时间小于当前时间 if expire_time < time.strftime(DT_FMT): update_value['expire_time'] = int(time.time() - 600) else: update_value['expire_time'] = str_to_tstamp( expire_time, DT_FMT) + 86399 else: update_value['expire_time'] = int(time.time() - 600) with get_connection_exception('qf_mchnt') as db: db.update('card_actv', update_value, {'id': d['id']}) return success({})
def POST(self): d = self.req.inputjson() userid = self.user.userid # 付费过期不能修改活动 mchnt = get_payinfo_ex( userid, service_code='card_actv', groupid=self.get_groupid()) if str(mchnt.get('expire_time')) < time.strftime(DATETIME_FMT): raise ParamError('付费已经到期了哦') # 获取活动信息 self.check_allow_change(d.get('id')) update_value = {} # 活动开始截止时间 for field in ('start_time', 'expire_time'): if d.get(field): if not is_valid_date(d[field]): raise ParamError('时间格式错误') if field == 'start_time': update_value[field] = str_to_tstamp(d[field], DT_FMT) else: update_value[field] = str_to_tstamp(d[field], DT_FMT)+86399 for field in ('obtain_amt', 'obtain_limit', 'goods_amt'): if d.get(field) and not is_valid_int(d[field]): raise ParamError('数据格式错误') # 修改活动状态 if is_valid_int(d.get('status')): if int(d['status']) in (ACTV_STATUS_NORMAL, ACTV_STAUS_STOPED): update_value['status'] = int(d['status']) # 结束申明 if int(d['status']) == ACTV_STAUS_STOPED and d.get('statement'): if d.get('statement'): statement = remove_emoji(d['statement']) if not 1 <= str_len(statement) <= 150: raise ParamError('停止活动声明应该是1至150位') update_value['statement'] = statement # 集点条件 if d.get('obtain_amt'): if d['obtain_amt'] < 0: raise ParamError('集点条件大于0元') update_value['obtain_amt'] = d['obtain_amt'] # 集点限制 if d.get('obtain_limit'): if d['obtain_limit'] < 0: raise ParamError('集点条件大于0元') update_value['obtain_limit'] = d['obtain_limit'] # 奖品名称 if d.get('goods_name'): d['goods_name'] = remove_emoji(d['goods_name']) if not 1 <= str_len(d['goods_name']) <= 8: raise ParamError('商品名长度是1至8位') update_value['goods_name'] = d['goods_name'] # 奖品金额 if d.get('goods_amt'): if d['goods_amt'] <= 0: raise ParamError('商品价格应大于0') update_value['goods_amt'] = d['goods_amt'] # 参与商户 if 'mchnt_id_list' in d: update_value['mchnt_id_list'] = self.get_mchnt_id_list( d['mchnt_id_list'].strip().split(','), int(d['id'])) if update_value: update_value['utime'] = int(time.time()) with get_connection_exception('qf_mchnt') as db: db.update('card_actv', update_value, {'id': d['id']}) return self.write(success({'id': d['id']}))
def _get_members(self, d): limit_members = 10 r = {} r['overdue_warn'], r['overdue_note'] = 0, '' with get_connection_exception('qf_mchnt') as db: where = {'userid': d['userid']} # total_num r['total_num'] = db.select_one('member', where=where, fields='count(1) as num')['num'] # 若未开通服务或者付费过期 if d['mchnt_info'][ 'overdue'] and r['total_num'] > limit_members and ( d['limit'] + d['offset'] >= limit_members): r['overdue_warn'] = 1 r['overdue_note'] = '未开通会员服务,仅可显示{num}个会员信息'.format( num=limit_members) d['limit'] = max(min(limit_members - d['offset'], d['limit']), 0) # members r['members'] = [] if d['limit']: fields = 'customer_id, txamt, num, last_txdtm, userid' other = '%s limit %s offset %s' % (d['orderby'], d['limit'], d['offset']) r['members'] = db.select('member', where=where, other=other, fields=fields) # 统计今日增长笔数 td = str_to_tstamp(time.strftime(DATE_FMT), DATE_FMT) r['add_members'] = db.select_one('member', where={ 'userid': d['userid'], 'ctime': ('>', td) }, fields='count(1) as num')['num'] cids = [i['customer_id'] for i in r['members']] if cids: spec = json.dumps({"user_id": cids}) try: profiles = thrift_callex(config.OPENUSER_SERVER, OpenUser, 'get_profiles', config.OPENUSER_APPID, spec) profiles = {i.user_id: i.__dict__ for i in profiles} # 处理返回值 for m in r['members']: info = profiles.get(m['customer_id'], {}) m['avatar'] = info.get('avatar') or config.HJ_AVATAR m['gender'] = info.get('gender', 1) m['nickname'] = info.get('nickname') or m['customer_id'] m['last_txdtm'] = tstamp_to_str(m['last_txdtm'], DATETIME_FMT) except: log.warn('get openuser_info error:%s' % traceback.format_exc()) raise ThirdError('获取消费者信息失败') return r
def _trans_input(self): data = {k: v.strip() for k, v in self.req.input().iteritems()} userid = int(self.user.userid) # 验证商户付费状态 if getattr(config, 'COUPON_CHECK_PAYINFO', True): mchnt = get_payinfo_ex(userid, service_code='coupon', groupid=self.get_groupid()) if not mchnt: raise ParamError('你的会员服务尚未开通,请联系业务员开通后再进行设置。') elif str(mchnt['expire_time']) <= time.strftime(DATETIME_FMT): raise ParamError('只有续费才能创建哦') fields = ('amt', 'num', 'obtain_limit_amt', 'use_limit_amt', 'coupon_lifetime', 'amt_min', 'amt_max', 'total_amt') for i in fields: data[i] = int(data.get(i) or 0) # 去除表情符 data['title'] = remove_emoji(data['title']) if not (1 <= str_len(data['title']) <= 12): raise ParamError('活动名称长度是1至12位') # 固定金额, 需要处理下 if data['num']: data['total_amt'] = data['num'] * data['amt'] data['amt_min'] = data['amt_max'] = data['amt'] # 红包金额小于100 if data['amt_max'] > 10000: raise ParamError('红包金额应小于100') # 红包最小金额小于最大金额 if data['amt_min'] > data['amt_max']: raise ParamError('红包奖励最大金额应该大于最小金额') # 红包奖励金额 if not data['amt_max']: raise ParamError('红包奖励金额应该大于0') # 红包预算 if not (0 < data['total_amt'] < 1000000): raise ParamError('红包预算应该大于0小于10000元') # 使用金额和红包金额 if data['use_limit_amt'] < data['amt_max']: raise ParamError('红包使用金额大于等于红包金额') # 有效时间 if not all( map(is_valid_date, [data['start_time'], data['expire_time']])): raise ParamError('时间格式不对') # 红包有效期 if data['coupon_lifetime'] <= 0: raise ParamError('优惠劵的有效时间大于0') # 红包截止日期 if data['start_time'] > data['expire_time']: raise ParamError('活动开始时间大于截止时间') data['type'] = covert(data.get('type', ''), int, 20) data['coupon_offset'] = covert(data.get('coupon_offset', ''), int, 0) data['start_time'] = str_to_tstamp(data['start_time'], DATE_FMT) data['expire_time'] = str_to_tstamp(data['expire_time'], DATE_FMT) + (24 * 60 * 60 - 1) data['userid'] = str(userid) return data
def _stats(self, d): def _get_coupon_stats(): '''红包活动(使用红包的数量)''' num = 0 with get_connection('qf_marketing') as db: where = { 'use_mchnt_id': str(d['userid']), 'create_time': ('>', td), 'type': ('in', (1, 2, 3)) } fields = 'count(1) as num, type' records = db.select('record', where=where, fields=fields, other='group by type') or [] nums = {i['type']: i['num'] for i in records} num = max(nums.get(1, 0) - nums.get(2, 0) - nums.get(3, 0), 0) return {'num': num} if num else None def _get_member_stats(): '''会员管理(新增会员数)''' num = 0 with get_connection('qf_mchnt') as db: where = {'userid': d['userid'], 'ctime': ('>', td)} fields = 'count(1) as num' num = db.select_one('member', where=where, fields=fields)['num'] return {'num': num} if num else None def _get_tx_stats(): '''数据魔方 (今日交易金额)''' amt = 0 with get_connection('qf_mchnt') as db: where = {'userid': d['userid'], 'ctime': ('>', td)} fields = 'sum(txamt) as amt' amt = db.select_one('member', where=where, fields=fields)['amt'] amt = int(amt or 0) return { 'amt': '{amt:.{width}f}'.format(amt=amt / 100.0, width=2 if amt % 100 else 0) } if amt else None def _get_card_stats(): '''会员集点 (今日集点数)''' num = 0 with get_connection('qf_mchnt') as db: where = {'userid': d['userid'], 'ctime': ('>', td)} fields = 'sum(pts) as num, type' records = db.select('pt_record', where=where, fields=fields, other='group by type') or [] nums = {i['type']: i['num'] for i in records} num = max(nums.get(1, 0) - nums.get(2, 0), 0) return {'num': num} if num else None td = str_to_tstamp(time.strftime(DATE_FMT), DATE_FMT) funcs = { 'HJ0009': _get_coupon_stats, 'HJ0011': _get_member_stats, 'HJ0014': _get_tx_stats, 'HJ0016': _get_card_stats, } # 获取会员功能服务列表 services = filter(lambda x: x.get('module') == 'member', config.SYSTEM_SERVICES) services = {i['code']: i for i in services} # 付费过期, 未付费 if d['mchnt_info']['overdue'] == 1 or not d['mchnt_info']['status']: return {k: v.get('note', '') for k, v in services.iteritems()} else: r = {} for k, v in services.iteritems(): if not v.get('stats_note'): r[k] = v.get('note') or '' else: stats = funcs[k]() if not stats: r[k] = v.get('note', '') else: r[k] = v['stats_note'].format(**stats) return r
def _update(): ''' 最新版本 ''' # 获取当前服务 cur_goods = err = None for goods in config.GOODS: if goods['code'] == goods_code: if goods.get('is_gratis'): err = '服务是免费' break cur_goods = goods break else: err = '未找到服务' if cur_goods['price']['code'] != order['price_code']: err = '服务没有该价格' if err: log.debug(err) return with get_connection('qf_mchnt') as db: # 获取当前的信息 upwhere = { 'goods_code': order['goods_code'], 'userid': order['userid'] } try: info = db.select_one('recharge', where=upwhere) except: info = None # 更新当前级别的信息 try: st = datetime.date.today() if info: exptm = info['expire_time'] if str(exptm) > time.strftime(DATETIME_FMT): st = datetime.date(year=exptm.year, month=exptm.month, day=exptm.day) add_conf = { cur_goods['price']['alidity']['unit']: cur_goods['price']['alidity']['key'] } end = str_to_tstamp( str(future(st, **add_conf)) + ' 23:59:59', DATETIME_FMT) # 若不存在,则直接插入 if info: updata = { 'expire_time': end, 'utime': int(time.time()), 'status': 2 } db.update('recharge', updata, upwhere) else: indata = {} indata['id'] = getid() indata['userid'] = order['userid'] indata['goods_code'] = order['goods_code'] indata['status'] = 2 indata['expire_time'] = end + cur_goods.get('free', 0) * 24 * 3600 indata['ctime'] = indata['utime'] = int(time.time()) db.insert('recharge', indata) except: log.warn('更新消费者有效期失败:%s' % traceback.format_exc()) # 更新低级别的服务 low_codes = { goods['code'] for goods in config.GOODS if not goods.get('is_gratis') and goods['vip'] < cur_goods['vip'] } if low_codes: content = '{}购买了{}高级服务,将所有低级服务折算'.format( time.strftime(DATETIME_FMT), order['goods_code']) now = int(time.time()) db.update(table='recharge', where={ 'goods_code': ('in', low_codes), 'userid': order['userid'], 'expire_time': ('>', now), }, values={ 'content': content, 'expire_time': now, 'utime': now })
def _query(self, d): rcard, rcustomer, overdue = {}, {}, 0 now = int(time.time()) # 获取生效的集点活动 with get_connection('qf_mchnt') as db: rcard = db.select_one( 'card_actv', where={ 'userid': self.get_userid_condition(d['userid']), 'expire_time': ('>=', now), 'start_time': ('<', now) }, fields=('id, start_time, expire_time, status, goods_name,' 'goods_amt, exchange_pt, obtain_amt, obtain_limit,' 'statement'), other='order by ctime desc') # 暂无生效的集点活动 if not rcard: return None, None, 0 # 商户过期信息 overdue = adjust_payinfo_ex( userid=d['userid'], service_code='card_actv', groupid=self.get_groupid(userid=d['userid']))['overdue'] with get_connection('qf_mchnt') as db: # 消费者信息 customer_info = db.select_one('member_pt', where={ 'activity_id': rcard['id'], 'customer_id': d['customer_id'] }) or {} # 若商户过期 if overdue: # 若是新消费者或者老商户且已经兑换过礼品, # 则不能继续集点活动了 if (not customer_info or (not customer_info['cur_pt'] and customer_info['total_pt'])): return None, None, overdue # 返回的消费者信息 rcustomer['cur_pt'] = customer_info.get('cur_pt') or 0 rcustomer['is_new'] = CardBase.is_new_card(d['userid'], d['customer_id'], d['src']) rcustomer['diff_obtain_amt'] = max( rcard['obtain_amt'] - d['txamt'], 0) rcustomer['card_id'] = customer_info.get('id') obtain_pts = min(d['txamt'] / rcard['obtain_amt'], rcard['obtain_limit'] or sys.maxint) rcustomer['obtain_pts'] = obtain_pts rcustomer['exchange'] = rcustomer['cur_pt'] / rcard['exchange_pt'] # 插入pt_record # 插入失败即代表已领取过集点 is_obtain = False try: # 若满足条件 if not rcustomer['diff_obtain_amt']: fields = [ 'userid', 'customer_id', 'out_sn', 'txamt', 'total_amt' ] pt_indata = {field: d[field] for field in fields} pt_indata['ctime'] = pt_indata['utime'] = now pt_indata['activity_id'] = rcard['id'] pt_indata['type'] = PT_RECORD_GET pt_indata['id'] = getid() pt_indata['pts'] = obtain_pts db.insert('pt_record', pt_indata) except: is_obtain = True # 若未领取集点 if not is_obtain: try: # 新集点卡消费者 if not customer_info: m = { field: d[field] for field in ['userid', 'customer_id', 'txamt', 'total_amt'] } if not obtain_pts: m['txamt'] = m['total_amt'] = 0 rcustomer['card_id'] = m['id'] = getid() m['activity_id'] = rcard['id'] m['ctime'] = m['utime'] = now m['cur_pt'] = m['total_pt'] = obtain_pts db.insert('member_pt', m) # 有集点的老客户 elif obtain_pts: umwhere = { 'activity_id': rcard['id'], 'customer_id': d['customer_id'] } umdata = { 'txamt': DBFunc('txamt+%s' % d['txamt']), 'total_amt': DBFunc('total_amt+%s' % d['total_amt']), 'total_pt': DBFunc('total_pt+%d' % obtain_pts), 'cur_pt': DBFunc('cur_pt+%d' % obtain_pts), 'utime': now } db.update('member_pt', umdata, umwhere) except: log.debug('更新消费者集点信息失败, %s' % traceback.format_exc()) else: rcustomer['cur_pt'] += obtain_pts # 获取到集点, 更新活动统计信息 if obtain_pts: try: ucwhere = {'id': rcard['id']} ucdata = { 'total_pt': DBFunc('total_pt+%d' % obtain_pts), 'utime': now } db.update('card_actv', ucdata, ucwhere) except: log.debug(traceback.format_exc()) # 延后跟新member_tag gevent.spawn(self.update, d['userid'], d['customer_id']) # 活动信息 rcard['id'] = str(rcard['id']) rcard['start_time'] = str_to_tstamp(str(rcard['start_time'])) rcard['expire_time'] = str_to_tstamp(str(rcard['expire_time'])) # 消费者 org_pt, now_pt = rcustomer['cur_pt'] - obtain_pts, rcustomer[ 'cur_pt'] rcustomer['add_exchange'] = (now_pt / rcard['exchange_pt'] - org_pt / rcard['exchange_pt']) rcustomer['diff_exchange'] = max( rcard['exchange_pt'] - rcustomer['cur_pt'] % rcard['exchange_pt'], 0) return rcard, rcustomer, overdue
def _modules_note(self, d): def is_create_actv(userid): '''是否创建过活动''' if not userid: return False key = '__mchnt_api_is_create_actv__' if redis_pool.sismember(key, userid): return True flag = None # 会员集点活动 with get_connection('qf_mchnt') as db: flag = db.select_one('card_actv', where={'userid': int(userid)}, fields='id') if flag: redis_pool.sadd(key, userid) return True # 会员通知 with get_connection('qf_mchnt') as db: flag = db.select_one('member_actv', where={'userid': int(userid)}, fields='id') if flag: redis_pool.sadd(key, userid) return True # 红包活动 with get_connection('qf_marketing') as db: flag = db.select_one('activity', where={'mchnt_id': str(userid)}, fields='id') if flag: redis_pool.sadd(key, userid) return True return False mchnt = d['mchnt_info'] title, link = '', '' # 新用户 if not mchnt['status']: title = '回头客少?好近会员帮你' link = config.OPEN_SERVICE_LINK # 付费和体验用户 else: # 若付费已经过期 if mchnt['overdue']: title = '服务到期,去续费' if not mchnt.get( 'num') else '%s个会员等待服务,去续费' % mchnt['num'] link = config.OPEN_SERVICE_LINK # 若付费未过期 else: if mchnt['left_day'] <= 5: tip = ('体验{day}到期,去开通' if mchnt['status'] == MCHNT_STATUS_FREE else '服务{day}到期,去续费') title = tip.format( day='%s天后' % mchnt['left_day'] if mchnt['left_day'] else '今日') link = config.OPEN_SERVICE_LINK elif is_create_actv(d['userid']): num = 0 with get_connection('qf_mchnt') as db: td = str_to_tstamp(time.strftime(DATE_FMT), DATE_FMT) where = { 'userid': d['userid'], 'ctime': ('<', td), 'last_txdtm': ('>', td) } num = db.select_one('member', where=where, fields='count(1) as num')['num'] title = '今日回头客%s人' % num if num else '' link = '' return {'member': {'title': title, 'link': link}}
def GET(self): if 'id' not in self.req.input(): raise ParamError('活动不存在') actv_id = self.req.input()['id'].strip() userid = int(self.user.userid) actv = {} with get_connection('qf_mchnt') as db: actv = db.select_one('actv_effect', where = { 'id' : actv_id, 'userid' : userid }) or {} if not actv: raise ParamError('活动不存在') if actv['type'] not in UserDefine.ACTV_EFFECTS: raise ParamError('活动类型错误') # 活动结案报告 params = json.loads(actv['content']) effect = copy.deepcopy(config.ACTV_EFFECT[actv['type']]) # 整理输出 result = {} for key, val in effect.iteritems(): if key in ('datas', 'effect'): param = params.get(key) or {} param = {k:(v/100.0 if k.endswith('amt') else v) for k,v in param.iteritems()} result[key] = [] for item in val: try: item['desc'] = item['desc'].format(**param) result[key].append(item) except: #log.debug(traceback.format_exc()) pass elif key == 'rank': try: result['rank'] = val.format(**params['rank']) except: result['rank'] = '' elif not key.startswith('_'): result[key] = val # 活动信息 datas = params.get('datas') or {} if datas: if actv['type'] == UserDefine.ACTV_EFFECT_SALE: datas['start_time'] = datas['create_time'] datas['expire_time'] =datas['redeem_end_date'] + ' 00:00:00' try: result['actv_info'] = { 'expire_time' : str_to_tstamp(datas['expire_time'], DATETIME_FMT), 'start_time' : str_to_tstamp(datas['start_time'], DATETIME_FMT), 'actv_name' : datas.get('title', '') } if actv['type'] == UserDefine.ACTV_EFFECT_CARD: result['actv_info']['actv_name'] = u'兑换{}活动'.format(params['datas']['goods_name']) except: log.debug(traceback.format_exc()) return self.write(success(result))
def GET(self): data = self.validator.data # 检查活动 self.check_allow_query(data['id']) # 排序 分页 data['limit'] = data['pagesize'] data['offset'] = data['pagesize'] * data['page'] other = ('order by utime desc limit {limit} ' 'offset {offset}'.format(**data)) records = None with get_connection('qf_mchnt') as db: records = db.select(table='exchange_record', where={ 'activity_id': data['id'], 'status': CODE_STATUS_EXCHANGED }, fields='customer_id, utime, code', other=other) if not records: return self.write(success({'records': []})) cids = {i['customer_id'] for i in records} spec = json.dumps({'user_id': list(cids)}) try: p = thrift_callex(config.OPENUSER_SERVER, OpenUser, 'get_profiles', config.OPENUSER_APPID, spec) infos = {i.user_id: i.__dict__ for i in p} except: log.warn(traceback.format_exc()) infos = {} # 处理返回值 for i in records: info = infos.get(i['customer_id']) or {} i['avatar'] = info.get('avatar') or config.HJ_AVATAR i['gender'] = info.get('gender') or 0 i['nickname'] = info.get('nickname') or '微信支付顾客' i['exchange_time'] = tstamp_to_str(i['utime'], DATETIME_FMT) i['code'] = '{:0>4d}'.format(i['code']) # 按日期整理结果 tidy_records = defaultdict(list) for i in records: t = tstamp_to_str(i['utime'], DATE_FMT) tidy_records[t].append(i) # 获取头部信息 last_day = str_to_tstamp(tstamp_to_str(records[-1]['utime'], DATE_FMT), DATE_FMT) sql = ( 'select FROM_UNIXTIME(utime, "%%Y-%%m-%%d") as date, ' 'count(id) as num from exchange_record ' 'where activity_id=%d and utime>=%s and status=%d ' 'group by FROM_UNIXTIME(utime, "%%Y%%m%%d") order by utime desc' % (int(data['id']), last_day, CODE_STATUS_EXCHANGED)) with get_connection_exception('qf_mchnt') as db: diff_days = db.query(sql) or [] ret = [] for i in diff_days: t = {} t['date'] = i['date'] t['total_num'] = i['num'] t['records'] = tidy_records.get(i['date']) or [] ret.append(t) return self.write(success({'records': ret}))