def POST(self, version='v1'): web.header('Content-Type', 'application/json') param = web.input(app_id='', dev_id='', ver_code='', session='', object_id='', progress='', tick='') if '' in (param.app_id, param.dev_id, param.ver_code, param.object_id, param.session, param.progress, param.tick): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) if not param.progress.isdigit(): return json.dumps({'ret' : -3, 'msg' : 'progress参数必须是数字'}) # 检查session登录 uname = app_helper.app_logged(param.session) if uname is None: return json.dumps({'ret' : -4, 'msg' : '无效的session'}) #-------------------------------------------------- r2 = db.obj_store.find_one({'obj_id' : param.object_id}) if r2 is None: return json.dumps({'ret' : -5, 'msg' : '错误的object_id'}) db.progress_info.update({'userid':uname['userid'],'obj_id':param.object_id},{'$set':{ 'progress' : int(param.progress), 'last_time' : app_helper.time_str(), }}, upsert=True) # 返回 return json.dumps({ 'ret' : 0, })
def log(act_user, log_event, log_message, order_id=None, log_json={}, send_to_log_server=1): # 访问记录 env_info = web.ctx.get('environ') if env_info: request_info = { 'remote_addr' : env_info.get('REMOTE_ADDR'), 'remote_port' : env_info.get('REMOTE_PORT'), 'request_method' : env_info.get('REQUEST_METHOD'), 'request_uri' : env_info.get('REQUEST_URI'), 'user_agent' : env_info.get('HTTP_USER_AGENT'), } else: request_info = {} # order_id 填在log_json里 if order_id: log_json['order_id']=order_id r=db.action_log.insert_one({ 'log_time' : app_helper.time_str(), 'act_user' : act_user, 'log_event' : log_event, 'log_message' : log_message, 'log_json' : log_json, # None 或 json 数据 'request_info' : request_info, 'send_to_log_server' : send_to_log_server, # 1 发送 0 不发送 }) #发到日志中心的log if send_to_log_server: log_push(r.inserted_id) return r.inserted_id
def POST(self): web.header('Content-Type', 'application/json') param = web.input(app_id='', session='', order_id='', star='', sign='') if '' in (param.app_id, param.session, param.order_id, param.star, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) uname = app_helper.logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign( [param.app_id, param.session, param.order_id, param.star]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) db_user = db.app_user.find_one({'uname': uname}, {'coupon': 1}) if db_user == None: # 不应该发生 return json.dumps({'ret': -5, 'msg': '未找到用户信息'}) # 订单打分 db.order_app.update_one({ 'order_id': param.order_id, 'user': uname }, { '$set': { 'star': int(param.star) }, '$push': { 'history': (app_helper.time_str(), uname, '订单打分') }, }) return json.dumps({'ret': 0, 'msg': '订单已打分!'}) else: return json.dumps({'ret': -4, 'msg': '无效的session'})
def POST(self, version='v2'): web.header('Content-Type', 'application/json') if version not in ('v2', 'v3'): return json.dumps({'ret': -999, 'msg': '版本错误!'}) print 'version=', version param = web.input(app_id='', session='', voice='', sign='') if '' in (param.app_id, param.session, param.voice, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) uname = app_helper.app_logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign( [param.app_id, param.session, param.voice]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) # 存入db db.customer_voice.insert_one({ 'uname': uname['uname'], 'voice': param.voice, 'time': app_helper.time_str(), }) # 返回 return json.dumps({'ret': 0}) else: return json.dumps({'ret': -4, 'msg': '无效的session'})
def POST(self): web.header('Content-Type', 'application/json') param = web.input(openid='', session_id='', order_id='', star='') if '' in (param.order_id, param.star): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) if param.openid=='' and param.session_id=='': return json.dumps({'ret' : -2, 'msg' : '参数错误1'}) # 同时支持openid和session_id if param.openid!='': uname = app_helper.check_openid(param.openid) else: uname = app_helper.wx_logged(param.session_id) if uname: db_user = db.app_user.find_one({'openid':uname['openid']},{'coupon':1}) if db_user==None: # 不应该发生 return json.dumps({'ret' : -5, 'msg' : '未找到用户信息'}) # 订单打分 db.order_app.update_one({'order_id' : param.order_id, 'user':{'$in':uname.values()}},{ '$set' : { 'star': int(param.star) }, '$push' : { 'history' : (app_helper.time_str(), uname['openid'], '订单打分')}, }) return json.dumps({'ret' : 0, 'msg' : '订单已打分!'}) else: return json.dumps({'ret' : -4, 'msg' : '无效的openid'})
def interface_log(url, param, result): r=db.interface_log.insert_one({ 'log_time' : app_helper.time_str(), 'url' : url, 'param' : param, 'result' : result, })
def POST(self, version='v2'): web.header('Content-Type', 'application/json') if version not in ('v2', 'v3'): return json.dumps({'ret': -999, 'msg': '版本错误!'}) print 'version=', version param = web.input(app_id='', session='', order_id='', sign='') if '' in (param.app_id, param.session, param.order_id, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) uname = app_helper.app_logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign( [param.app_id, param.session, param.order_id]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) db_user = db.app_user.find_one({'uname': uname['uname']}, {'coupon': 1}) if db_user == None: # 不应该发生 return json.dumps({'ret': -5, 'msg': '未找到用户信息'}) # 获得订单 db_order = db.order_app.find_one( { 'order_id': param.order_id, 'user': { '$in': uname.values() } }, { 'status': 1, 'cart': 1, 'due': 1, 'shop': 1 }) if db_order == None: return json.dumps({'ret': -3, 'msg': '未找到订单!'}) elif db_order['status'] != 'DUE': return json.dumps({'ret': -3, 'msg': '不是待付款订单!'}) # 取消订单 db.order_app.update_one({ 'order_id': param.order_id, }, { '$set': { 'status': 'CANCEL' }, '$push': { 'history': (app_helper.time_str(), uname['uname'], '取消账单') }, }) return json.dumps({'ret': 0, 'msg': '订单已取消!'}) else: return json.dumps({'ret': -4, 'msg': '无效的session'})
def check_wx_user(wx_user): db_wx = db.wx_user.find_one({'wx_user': wx_user}, {'owner': 1}) if db_wx != None: # 已登记 return db_wx['owner'] else: # 未登记 db.wx_user.insert_one({ 'wx_user': wx_user, 'owner': '', 'time': time_str() }) return ''
def check_rand(param, version='v1'): session = app_helper.get_session(param.session) if session == None: return json.dumps({'ret': -4, 'msg': '无效的session'}) if session.get('pwd_fail', 0) >= 5: print '========> 请重新获取验证码', session.get('pwd_fail', 0) return json.dumps({'ret': -5, 'msg': '请重新获取验证码'}) if param.rand.strip() != session['rand']: # #2015-12-22,gt if session['uname'] in app_helper.INNER_NUM.keys( ) and param.rand.strip() == app_helper.INNER_NUM[session['uname']]: pass else: db.app_sessions.update_one( {'session_id': session['session_id']}, {'$inc': { 'pwd_fail': 1 }}) return json.dumps({'ret': -5, 'msg': '短信验证码错误'}) db.app_sessions.update_one( {'session_id': session['session_id']}, {'$set': { 'login': 1, 'attime': time.time(), }}) # 更新登录时间 2016-12-28, gt db.app_user.update_one( {'uname': session['uname']}, { '$set': { 'last_time': app_helper.time_str(), 'passwd': app_helper.my_crypt(param.passwd), 'reg_ok': 1, # 标记已注册成功,reg_ok==0属于注册过程中的 2016-06-21 } }) ## 返回 return json.dumps({ 'ret': 0, 'data': { 'session': session['session_id'], 'login': True, 'uname': session['uname'], 'alert': True, # 'message': '测试弹窗', } })
def update_event_status(event_id, status, msg=''): return db.event_queue.update_one({'_id': event_id}, { '$set': { 'status': status, 'lock': 0 }, '$inc': { 'count': 1 }, '$push': { 'history': (app_helper.time_str(), msg) } })
def check_send_freq(mobile): tick = int(time.time()) r = db.sms_sent_log.find_one({'mobile': mobile}) if r == None: # 没发过 db.sms_sent_log.insert_one({ 'mobile': mobile, 'last_t': tick, # 最近一次 tick 'history': [app_helper.time_str()], 'in_hour': tick, # 1小时计数 tick 'n_in_hour': 1, # 1小时计数 }) else: if tick - r['last_t'] < 60: # 每次间隔大于1分钟 print '短信 -------> ', mobile, '------> 1分钟内多次!' return False if tick - r['in_hour'] < 3600 and r['n_in_hour'] >= 10: # 1小时内发生不超过10次 print '短信 -------> ', mobile, '------> 1小时内超过10次!' return False # 更新时间记录 db.sms_sent_log.update_one( {'mobile': mobile}, { '$set': { 'last_t': tick, 'in_hour': tick if tick - r['in_hour'] > 3600 else r['in_hour'], 'n_in_hour': 1 if tick - r['in_hour'] > 3600 else (r['n_in_hour'] + 1), }, '$push': { 'history': app_helper.time_str(), # 记录发送历史, 2017-06-28, gt }, }) return True
def run(self): self._tname = threading.currentThread().getName() print 'Thread - started', self._tname, self._tid while 1: try: check_event(self._tname, self._tid) except Exception, e: print 'Error: thread fail', self._tid, app_helper.time_str() traceback.print_exc() # 周期性打印日志 sys.stdout.flush() time.sleep(0.1)
def POST(self): web.header('Content-Type', 'application/json') param = web.input(app_id='', session='', secret='', sign='') if '' in (param.app_id, param.session, param.secret, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) uname = app_helper.logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign( [param.app_id, param.session, param.secret]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) db_user = db.app_user.find_one({'uname': uname}, {'coupon': 1}) if db_user == None: # 不应该发生 return json.dumps({'ret': -5, 'msg': '未找到用户信息'}) # 检查是否有新红包 app_helper.check_hb(uname) # 这里应该增加对有效期的检查!!! coupon = [] unused = 0 for i in db_user['coupon']: if app_helper.time_str(format=1) > i[1]: # 过期抵用券不返回 2015-08-22 continue coupon.append({ 'id': i[0], 'valid': i[1], 'cash': i[2], 'status': 'unused' if i[3] == 1 else 'used', }) unused += (1 if i[3] == 1 else 0) # 返回 return json.dumps({ 'ret': 0, 'data': { 'coupon': coupon, 'total': len(coupon), 'unused': unused, } }) else: return json.dumps({'ret': -4, 'msg': '无效的session'})
def bind_wx_user(wx_user, fair_user): # 关注时, fair_user 为region_id # 取消关注时,fair_user 为 'N/A' check_wx_user(wx_user) if fair_user == 'N/A': push_data = 'unsubscribe' else: push_data = 'subscribe' db.wx_user.update_one({'wx_user': wx_user}, { '$set': { 'owner': fair_user, 'last_tick': int(time.time()) }, '$push': { 'history': (time_str(), push_data, fair_user) }, })
def make_trade_order(userid, amount, trade_type, comment, pay_type='cash'): trade_order = { 'order_trade_id': app_helper.get_new_order_id(), 'userid': userid, 'total_sum': amount, 'trade_type': trade_type, # receipt 收款 refund 退款 consume 消费 'pay_type': pay_type, 'pay_time': app_helper.time_str(), 'cash_sum': amount, 'comment': comment, } db.order_trade.update_one( {'order_trade_id': trade_order['order_trade_id']}, {'$set': trade_order}, upsert=True) return trade_order['order_trade_id']
def POST(self): web.header('Content-Type', 'application/json') param = web.input(openid='', session_id='') if param.openid == '' and param.session_id == '': return json.dumps({'ret': -2, 'msg': '参数错误1'}) # 同时支持openid和session_id if param.openid != '': uname = app_helper.check_openid(param.openid) else: uname = app_helper.wx_logged(param.session_id) if uname: db_user = db.app_user.find_one({'openid': uname['openid']}, {'coupon': 1}) if db_user == None: # 不应该发生 return json.dumps({'ret': -5, 'msg': '未找到用户信息'}) # 这里应该增加对有效期的检查!!! coupon = [] unused = 0 for i in db_user['coupon']: if app_helper.time_str(format=1) > i[1]: # 过期抵用券不返回 2015-08-22 continue coupon.append({ 'id': i[0], 'valid': i[1], 'cash': i[2], 'status': 'unused' if i[3] == 1 else 'used', }) unused += (1 if i[3] == 1 else 0) # 返回 return json.dumps({ 'ret': 0, 'data': { 'coupon': coupon, 'total': len(coupon), 'unused': unused, } }) else: return json.dumps({'ret': -4, 'msg': '无效的openid'})
def process_wxpay_notify(order_id, pay_data): print 'wxpay 付款通知', order_id r2 = db.order_recharge.find_one({'recharge_id': order_id}) if r2 is None: print 'process_iap_notify: 未找到订单' return 'FAIL', '未找到订单' print 'status', r2['status'] if r2['status'] == 'PAID': print 'process_iap_notify: 此单已充值' return 'DONE', '此单已充值' xml = ET.fromstring(pay_data) result_code = xml.find('result_code').text if result_code == 'SUCCESS': # 有付款 wxpay_total = xml.find('total_fee').text # 微信支付实际支付,单位:分 wxpay_total_fen = int(wxpay_total) wx_trade_no = xml.find('transaction_id').text # 充值操作 - 按实际付款金额充值,如果做优惠,在这里修改 order_trade_id = credit_helper.save_to_balance(r2['userid'], wxpay_total_fen) # 修改充值订单状态 db.order_recharge.update_one( {'recharge_id': order_id}, { '$set': { 'status': 'PAID', 'order_trade_flow_id': order_trade_id, 'wx_trade_no': wx_trade_no, 'wxpay_total': wxpay_total_fen, # 实际支付金额 }, '$push': { 'process_notify_msg': (app_helper.time_str(), '支付完成') }, }) else: print '非付款通知', order_id, pay_data.get('trade_status') return 'DONE', '支付完成'
def process_alipay_notify(order_id, pay_data): print 'alipay 付款通知', order_id r2 = db.order_recharge.find_one({'recharge_id': order_id}) if r2 is None: print 'process_iap_notify: 未找到订单' return 'FAIL', '未找到订单' print 'status', r2['status'] if r2['status'] == 'PAID': print 'process_iap_notify: 此单已充值' return 'DONE', '此单已充值' if pay_data.get('trade_status') == 'TRADE_SUCCESS' and ( not pay_data.has_key('refund_status')): alipay_total = param.get('total_fee', '0.00') # 支付宝实际支付 alipay_total_fen = int(float(alipay_total) * 100) # 单位:分 ali_trade_no = param.get('trade_no') # 充值操作 - 按实际付款金额充值,如果做优惠,在这里修改 order_trade_id = credit_helper.save_to_balance(r2['userid'], alipay_total_fen) # 修改充值订单状态 db.order_recharge.update_one( {'recharge_id': order_id}, { '$set': { 'status': 'PAID', 'order_trade_flow_id': order_trade_id, 'ali_trade_no': ali_trade_no, 'alipay_total': alipay_total_fen, # 实际支付金额 }, '$push': { 'process_notify_msg': (app_helper.time_str(), '支付完成') }, }) else: print '非付款通知', order_id, pay_data.get('trade_status') return 'DONE', '支付完成'
def POST(self): web.header("Content-Type", "application/json") param = web.input(session_id='', node_id='', correct_note='', source="cnnc") print param if param.session_id == '': return json.dumps({'ret': -1, 'msg': 'session参数错误'}) uname = app_helper.wx_logged(param.session_id) if uname is None: return json.dumps({'ret': -2, 'msg': '无效的session_id'}) if param.node_id == '': return json.dumps({'ret': -2, 'msg': '参数错误'}) db.correct.insert_one({ 'node_id': param['node_id'], 'note': param['correct_note'], 'openid': uname['openid'], 'time_t': app_helper.time_str(), # 提交时间 'status': 'WAIT', # WAIT 等待处理,PASS 接受,NOGO 拒绝 'source': param['source'], # 2019-10-29, 区分来源 }) if param['source'] == 'tnm': r2 = db.tnm.update_one({'_id': ObjectId(param['node_id'])}, {'$set': { 'node_question': True }}) else: r2 = db.nodes.update_one({'_id': ObjectId(param['node_id'])}, {'$set': { 'node_question': True }}) print r2.matched_count, r2.modified_count return json.dumps({'ret': 0, 'data': {}})
def POST(self): web.header('Content-Type', 'application/json') param = web.input(openid='', session_id='', order_id='') if param.order_id=='': return json.dumps({'ret' : -2, 'msg' : '参数错误'}) if param.openid=='' and param.session_id=='': return json.dumps({'ret' : -2, 'msg' : '参数错误1'}) # 同时支持openid和session_id if param.openid!='': uname = app_helper.check_openid(param.openid) else: uname = app_helper.wx_logged(param.session_id) if uname: db_user = db.app_user.find_one({'openid':uname['openid']},{'coupon':1}) if db_user==None: # 不应该发生 return json.dumps({'ret' : -5, 'msg' : '未找到用户信息'}) # 获得订单 db_order = db.order_app.find_one( {'order_id' : param.order_id, 'user': {'$in':uname.values()}}, {'status':1, 'cart':1, 'due':1, 'shop':1} ) if db_order==None: return json.dumps({'ret' : -3, 'msg' : '未找到订单!'}) elif db_order['status']!='DUE': return json.dumps({'ret' : -3, 'msg' : '不是待付款订单!'}) # 取消订单 db.order_app.update_one({'order_id' : param.order_id,},{ '$set' : { 'status':'CANCEL' }, '$push' : { 'history' : (app_helper.time_str(), uname['openid'], '取消账单')}, }) return json.dumps({'ret' : 0, 'msg' : '订单已取消!'}) else: return json.dumps({'ret' : -4, 'msg' : '无效的openid'})
def text_process(self): # 处理文本消息回复 content = self.xml.find("Content").text #cmd0 = content.split() #content_text = cmd0[0].lower() content_text = content.strip() print '-------------------> recv text' print setting.region_id # 记录用户留言 db.wx_text_log.insert_one({ 'openid': self.fromUser, 'text': content_text, 'time_t': app_helper.time_str(), }) text_res = self.get_text_reply(content_text.lower()) if text_res != None: return self.reply_text(text_res) media_res = self.get_media_reply(content_text.lower()) if media_res != None: return self.reply_media(media_res) # 检查规则库 2019-03-19 from libs import bayes_helper r = bayes_helper.getReply(content_text) if r is not None: if r['reply_type'] == 'link': # 返回链接 return self.reply_media([ (r['title'], u'无需关注公众号!还免费的哦!', u'http:///static/image/logo.png', r['reply']) ]) else: return self.reply_text(r['reply']) # 机器人回答 from talkbot_lib import gensim_bot return self.reply_text(gensim_bot.qa_bot_db(content_text))
def POST(self): web.header('Content-Type', 'application/json') param = web.input(openid='', session_id='', order_id='', pay_type='', data='') print param if '' in (param.order_id, param.pay_type): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) if param.openid=='' and param.session_id=='': return json.dumps({'ret' : -2, 'msg' : '参数错误1'}) # 同时支持openid和session_id if param.openid!='': uname = app_helper.check_openid(param.openid) else: uname = app_helper.wx_logged(param.session_id) if uname: db_user = db.app_user.find_one({'openid':uname['openid']},{'coupon':1, 'credit':1}) if db_user==None: # 不应该发生 return json.dumps({'ret' : -5, 'msg' : '未找到用户信息'}) # 支付操作:1,记录订单支付,2.改变订单状态,3.修改库存显示 !!!!!! # 获得订单 db_order = db.order_app.find_one( {'order_id' : param.order_id}, #{'status':1, 'cart':1, 'due':1, 'shop':1} {'_id':0} ) if db_order==None: return json.dumps({'ret' : -3, 'msg' : '未找到订单!'}) # 支付宝和微信支付订单,已PAID说明提前收到异步通知 if db_order['status']=='PAID' and param.pay_type in ('ALIPAY','WXPAY'): # 记录此次调用 db.order_app.update_one( { 'order_id' : param.order_id, }, { '$set' : { 'pay_type' : param.pay_type, 'pay' : db_order['due'], 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), }, '$push' : { 'history' : (app_helper.time_str(), uname['openid'], '提交付款')}, } ) return json.dumps({'ret' : 0, 'data' : { 'order_id' : param.order_id, 'due' : db_order['due'], 'paid' : db_order['due'], 'status' : '已支付' }}) # 只能处理未支付订单 if db_order['status']!='DUE': return json.dumps({'ret' : -3, 'msg' : '不是待付款订单!'}) # 余额支付和支付宝/微信支付未到账处理 if param.pay_type=='CREDIT': # 检查余额是否够支付 if float(db_order['due'])>db_user.get('credit',0.0): return json.dumps({'ret' : -6, 'msg' : '余额不足!'}) # 使用的优惠券失效 #db_user = db.app_user.find_one({'uname':r['uname']}) coupon = [] if db_order['coupon']!=None: for i in db_user['coupon']: if i[0]==db_order['coupon'][0]: # 这次使用 #coupon.append((i[0],i[1],i[2],0)) i2=list(i) i2[3]=0 coupon.append(i2) else: coupon.append(i) else: coupon = db_user['coupon'] # 更新优惠券 db.app_user.update_one({'openid':db_order['uname']}, {'$set':{'coupon':coupon}}) # 正常减库存! # item = [ product_id, num, num2, price] # k - num 库存数量 print "修改库存." b2 = [] # C端商品 b3 = [] # B3整箱预售商品 b3_total = 0.0 for item in db_order['cart']: #r3 = db.sku_store.find_one({'product_id' : item['product_id']}, # {'list_in_app':1}) #if r3['list_in_app']==3: # B3商品不需要改库存 # b3_total += float(item['price']) # b3.append(item) # item['title'] = item['title']+u'(整箱预售,次日送达)' # b2.append(item) # continue # 买一送一 if item['product_id'] in app_helper.buy_1_give_1: lc_num2 = float(item['num2']) item['num2'] = int(lc_num2 + lc_num2) item['title'] = item['title'].replace(u'买一送一',u'特惠活动') # 过滤数量价格为零的 if item['num2']==0 and float(item['price'])==0.0: continue r = db.inventory.find_one_and_update( # 不检查库存,有可能负库存 { 'product_id' : item['product_id'], 'shop' : db_order['shop'], }, { '$inc' : { 'num' : 0-float(item['num2']), # num2 实际购买数量 'pre_pay_num' : float(item['num2']), # 记录预付数量 } #'$push' : { 'history' : (helper.time_str(), # helper.get_session_uname(), '售出 %s' % str(item['num']))}, }, {'_id':1} ) #print r if r==None: # 不应该发生 return json.dumps({'ret' : -9, 'msg' : '修改库存失败,请联系管理员!'}) else: b2.append(item) # 更新第3方库存 2015-10-10 app_helper.elm_modify_num(db_order['shop'], item['product_id']) # 检查是否有b3商品, 3种情况 # 1. b2, b3 都有,拆单 # 2. 只有b3,站点改为B3站点,保留收货站点 # 3. 只有b2,保持订单不变 #print b2 #print b3 if len(b3)>0 and (len(b2)-len(b3))>0: # 情况1 print "拆单" r4 = db_order.copy() r4['order_id'] = r4['order_id']+u'-b3' r4['shop_0'] = r['shop'] r4['shop'] = ObjectId(setting.B3_shop) r4['cart'] = b3 r4['status'] = 'PAID' r4['ali_trade_no'] = param.get('trade_no') r4['paid_time'] = param.get('gmt_payment') r4['paid_tick'] = int(time.time()) r4['history'] = [(app_helper.time_str(), 'credit', '余额付款-拆单')] r4['total'] = '%.2f' % b3_total r4['cost'] = '0.00' r4['coupon_disc'] = '0.00' r4['first_disc'] = '0.00' r4['delivery_fee'] = '0.00' r4['due'] = '0.00' db.order_app.insert_one(r4) # 增加子订单 elif len(b3)>0: # 情况 2 print "订单改到B3站点" db.order_app.update_one({'order_id':param.order_id},{'$set' : { 'shop_0' : r['shop'], 'shop' : ObjectId(setting.B3_shop), }}) else: # 情况3,什么都不做 print "订单保持不变" # 更新销货单信息 db.order_app.update_one({'order_id' : param.order_id,},{ '$set' : { 'status' : 'PAID', 'cart' : b2, # 更新购物车 2015-09-11 'pay_type' : param.pay_type, 'pay' : db_order['due'], 'paid_time' : app_helper.time_str(), 'paid_tick' : int(time.time()), }, '$push' : { 'history' : (app_helper.time_str(), uname['openid'], '余额付款')}, }) # 消费余额 db.app_user.update_one({'openid' : uname['openid'],},{ '$inc' : { 'credit' : 0-float(db_order['due']), }, '$push' : { 'history' : (app_helper.time_str(), uname['openid'], '消费余额 %s' % db_order['due'].encode('utf-8')) }, }) elif param.pay_type in ('ALIPAY', 'WXPAY'): # 更新销货单信息, r = db.order_app.find_one_and_update( { 'order_id' : param.order_id, 'status' : 'DUE' }, { '$set' : { 'status' : 'PREPAID', 'pay_type' : param.pay_type, 'pay' : db_order['due'], 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), 'pay_data' : param.data, }, '$push' : { 'history' : (app_helper.time_str(), uname['openid'], '提交付款')}, }, {'status':1} ) # 如果不是DUE,说明已收到异步通知 if r==None: db.order_app.update_one( { 'order_id' : param.order_id, }, { '$set' : { 'pay_type' : param.pay_type, 'pay' : db_order['due'], 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), }, '$push' : { 'history' : (app_helper.time_str(), uname['openid'], '提交付款')}, } ) # 返回 return json.dumps({'ret' : 0, 'data' : { 'order_id' : param.order_id, 'due' : db_order['due'], 'paid' : db_order['due'], 'status' : '已支付' }}) else: return json.dumps({'ret' : -4, 'msg' : '无效的openid'})
def POST(self, version='v2'): web.header('Content-Type', 'application/json') if version not in ('v2','v3'): return json.dumps({'ret' : -999, 'msg' : '版本错误!'}) print 'version=',version param = web.input(app_id='', session='', order_id='', pay_type='', data='', sign='') print param if '' in (param.app_id, param.session, param.order_id, param.pay_type, param.sign): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) uname = app_helper.app_logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign([param.app_id, param.session, param.order_id, param.pay_type, param.data]) if md5_str!=param.sign: return json.dumps({'ret' : -1, 'msg' : '签名验证错误'}) db_user = db.app_user.find_one({'uname':uname['uname']},{'coupon':1, 'credit':1}) if db_user==None: # 不应该发生 return json.dumps({'ret' : -5, 'msg' : '未找到用户信息'}) # 支付操作:1,记录订单支付,2.改变订单状态,3.修改库存显示 !!!!!! # 获得订单 db_order = db.order_app.find_one( {'order_id' : param.order_id}, #{'status':1, 'cart':1, 'due':1, 'shop':1} ) if db_order==None: return json.dumps({'ret' : -3, 'msg' : '未找到订单!'}) # 支付宝和微信支付订单,已PAID说明提前收到异步通知 if db_order['status']=='PAID' and param.pay_type in ('ALIPAY','WXPAY'): # 记录此次调用 db.order_app.update_one( { 'order_id' : param.order_id, }, { '$set' : { 'pay_type' : param.pay_type, 'pay' : db_order.get('due3', db_order['due']), 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), }, '$push' : { 'history' : (app_helper.time_str(), uname['uname'], '提交付款')}, } ) return json.dumps({'ret' : 0, 'data' : { 'order_id' : param.order_id, 'due' : db_order.get('due3', db_order['due']), 'paid' : db_order.get('due3', db_order['due']), 'status' : '已支付', 'alert' : False, 'message' : '测试信息, 已经收到异步通知了', 'url' : 'http://app-test.urfresh.cn' }}) # 只能处理未支付订单 if db_order['status']!='DUE': return json.dumps({'ret' : -3, 'msg' : '不是待付款订单!'}) # 余额支付和支付宝/微信支付未到账处理 if param.pay_type=='CREDIT': # 余额支付0元提交的问题,原因未知 2015.08.20 if round(float(db_order['due']),2)<=0.0: return json.dumps({'ret' : -2, 'msg' : '参数错误'}) # 检查余额是否够支付 if float(db_order['due'])>db_user.get('credit',0.0): return json.dumps({'ret' : -6, 'msg' : '余额不足!'}) # 使用的优惠券失效 #db_user = db.app_user.find_one({'uname':r['uname']}) coupon = [] if db_order['coupon']!=None: for i in db_user['coupon']: if i[0]==db_order['coupon'][0]: # 这次使用 #coupon.append((i[0],i[1],i[2],0)) i2=list(i) i2[3]=0 coupon.append(i2) else: coupon.append(i) else: coupon = db_user['coupon'] # 未处理首单送券的逻辑 # 更新优惠券 db.app_user.update_one({'uname':db_order['uname']}, {'$set':{'coupon':coupon}}) # 邀请码用户送抵用券 2015-10-24 invitation = db_user.get('invitation', '') if invitation!='' and db_user.get('invite_coupon_has_sent', 0)==0: # 已填邀请码并且未送过券 coupon_user = db.app_user.find_one({'my_invit_code':invitation},{'uname':1}) if coupon_user: # 送邀请码用户抵用券 print '送邀请码用户抵用券' valid = app_helper.time_str(time.time()+3600*24*30, 1) db.app_user.update_one({'uname':coupon_user['uname']},{'$push':{ 'coupon' : (app_helper.my_rand(), valid, '5.00', 1, 19.9, 'apple') }}) # 设置已送标志 db.app_user.update_one({'uname':r['uname']}, {'$set':{'invite_coupon_has_sent':1}}) # 正常减库存! # item = [ product_id, num, num2, price] # k - num 库存数量 print "修改库存." b2 = [] # C端商品 b3 = [] # B3整箱预售商品 b3_total = 0.0 for item in db_order['cart']: # 记录销售量 db.sku_store.update_one({'product_id' : item['product_id']}, {'$inc' : {'volume' : float(item['num2'])}} ) #r3 = db.sku_store.find_one({'product_id' : item['product_id']}, # {'list_in_app':1}) #if r3['list_in_app']==3: # B3商品不需要改库存 # b3_total += float(item['price']) # b3.append(item) # item['title'] = item['title']+u'(整箱预售,次日送达)' # b2.append(item) # continue # 买一送一 if item.has_key('numyy'): # v3 2015-10-25 if item['product_id'] in app_helper.buy_X_give_Y.keys(): print '买X送Y' #item['num2'] = int(float(item['num2']) + float(item['numyy'])) #item['title'] = item['title'] + u'特惠活动' else: if item['product_id'] in app_helper.buy_1_give_1: print '买一送一' lc_num2 = float(item['num2']) item['num2'] = int(lc_num2 + lc_num2) item['title'] = item['title'].replace(u'买一送一',u'特惠活动') # 过滤数量价格为零的 if item['num2']==0 and float(item['price'])==0.0: continue # num2 实际购买数量, numyy 赠送数量, v3之后才有munyy 2015-10-20 num_to_change = float(item['num2']) + float(item.get('numyy', 0.0)) r = db.inventory.find_one_and_update( # 不检查库存,有可能负库存 { 'product_id' : item['product_id'], 'shop' : db_order['shop'], }, { '$inc' : { 'num' : 0-num_to_change, # num2 实际购买数量 'pre_pay_num' : num_to_change, # 记录预付数量 } #'$push' : { 'history' : (helper.time_str(), # helper.get_session_uname(), '售出 %s' % str(item['num']))}, }, {'_id':1} ) #print r if r==None: # 不应该发生 return json.dumps({'ret' : -9, 'msg' : '修改库存失败,请联系管理员!'}) else: b2.append(item) # 更新第3方库存 2015-10-10 app_helper.elm_modify_num(db_order['shop'], item['product_id']) # 检查是否有b3商品, 3种情况 # 1. b2, b3 都有,拆单 # 2. 只有b3,站点改为B3站点,保留收货站点 # 3. 只有b2,保持订单不变 #print b2 #print b3 if len(b3)>0 and (len(b2)-len(b3))>0: # 情况1 print "拆单" r4 = db_order.copy() r4['order_id'] = r4['order_id']+u'-b3' r4['shop_0'] = db_order['shop'] r4['shop'] = ObjectId(setting.B3_shop) r4['cart'] = b3 r4['status'] = 'PAID' r4['ali_trade_no'] = param.get('trade_no') r4['paid_time'] = param.get('gmt_payment') r4['paid_tick'] = int(time.time()) r4['history'] = [(app_helper.time_str(), 'credit', '余额付款-拆单')] r4['total'] = '%.2f' % b3_total r4['cost'] = '0.00' r4['coupon_disc'] = '0.00' r4['first_disc'] = '0.00' r4['delivery_fee'] = '0.00' r4['due'] = '0.00' db.order_app.insert_one(r4) # 增加子订单 elif len(b3)>0: # 情况 2 print "订单改到B3站点" # 如果订单地址不再配送范围,则由b3直接发出, 2015-10-18 if db_order.get('poly_shop', 1)==1: # 默认到店配送 print 'b3配送到店' shop_0 = db_order['shop'] else: print 'b3直接发货' shop_0 = ObjectId(setting.B3_shop) db.order_app.update_one({'order_id':param.order_id},{'$set' : { 'shop_0' : shop_0, 'shop' : ObjectId(setting.B3_shop), }}) else: # 情况3,什么都不做 print "订单保持不变" # 推送通知 #if len(db_order['uname'])==11 and db_order['uname'][0]=='1': # jpush.jpush('已收到您的付款,我们会尽快处理。', db_order['uname']) # 更新销货单信息 db.order_app.update_one({'order_id' : param.order_id},{ '$set' : { 'status' : 'PAID', 'cart' : b2, # 更新购物车 2015-09-11 'pay_type' : param.pay_type, 'pay' : db_order['due'], 'paid_time' : app_helper.time_str(), 'paid_tick' : int(time.time()), 'credit_total' : db_order['due'], # 2015-11-24 }, '$push' : { 'history' : (app_helper.time_str(), uname['uname'], '余额付款')}, }) # 消费余额 db.app_user.update_one({'uname' : uname['uname'],},{ '$inc' : { 'credit' : 0-float(db_order['due']), }, '$push' : { 'credit_history' : ( # 专门记录余额消费 app_helper.time_str(), '消费余额', '-%.2f' % float(db_order['due'].encode('utf-8')), '订单: %s' % param.order_id.encode('utf-8') ) }, }) elif param.pay_type in ('ALIPAY', 'WXPAY'): # 更新销货单信息, r = db.order_app.find_one_and_update( { 'order_id' : param.order_id, 'status' : 'DUE' }, { '$set' : { 'status' : 'PREPAID', 'pay_type' : param.pay_type, 'pay' : db_order.get('due3', db_order['due']), 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), 'pay_data' : param.data, }, '$push' : { 'history' : (app_helper.time_str(), uname['uname'], '提交付款')}, }, {'status':1} ) # 如果不是DUE,说明已收到异步通知 if r==None: db.order_app.update_one( { 'order_id' : param.order_id, }, { '$set' : { 'pay_type' : param.pay_type, 'pay' : db_order.get('due3', db_order['due']), 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), }, '$push' : { 'history' : (app_helper.time_str(), uname['uname'], '提交付款')}, } ) # 返回 return json.dumps({'ret' : 0, 'data' : { 'order_id' : param.order_id, 'due' : db_order.get('due3', db_order['due']), 'paid' : db_order.get('due3', db_order['due']), 'status' : '已支付', 'alert' : False, 'message' : '测试信息,还未收到异步通知', 'url' : 'http://app-test.urfresh.cn' }}) else: return json.dumps({'ret' : -4, 'msg' : '无效的session'})
def process_iap_notify(order_id, pay_data): print 'IAP付款校验', order_id check_data = iap_check(pay_data) if check_data is None: print 'process_iap_notify: 校验数据失败' return 'WAIT', '校验数据失败' # 置为 WAIT, 重新校验,backrun会控制重试10次 # 检查实际充值金额与订单提交的是否一致 r2 = db.order_recharge.find_one({'recharge_id': order_id}) if r2 is None: print 'process_iap_notify: 未找到订单' return 'FAIL', '未找到订单' if check_data['status'] != 0: print 'process_iap_notify: 数据校验失败 status=%d' % check_data['status'] return 'FAIL', '数据校验失败 status=%d' % check_data['status'] print 'status', r2['status'] if r2['status'] == 'PAID': print 'process_iap_notify: 此单已充值' return 'DONE', '此单已充值' price_item = find_deposit_price( check_data['receipt']['in_app'][0]['product_id']) if price_item is None: db.order_recharge.update_one({'recharge_id': order_id}, { '$set': { 'status': 'FAIL' }, '$push': { 'process_notify_msg': (app_helper.time_str(), '价格id错误') }, }) print 'process_iap_notify: 价格id错误' return 'FAIL', '价格id错误' if int(r2['due']) != int(check_data['receipt']['in_app'][0] ['quantity']) * price_item['price']: db.order_recharge.update_one({'recharge_id': order_id}, { '$set': { 'status': 'FAIL' }, '$push': { 'process_notify_msg': (app_helper.time_str(), '充值金额不相符') }, }) print 'process_iap_notify: 充值金额不相符' return 'FAIL', '充值金额不相符' # 充值操作 - 按实际付款金额充值,如果做优惠,在这里修改 order_trade_id = credit_helper.save_to_balance(r2['userid'], int(r2['due'])) # 修改充值订单状态 db.order_recharge.update_one({'recharge_id': order_id}, { '$set': { 'status': 'PAID', 'order_trade_flow_id': order_trade_id }, '$push': { 'process_notify_msg': (app_helper.time_str(), '支付完成') }, }) return 'DONE', '支付完成'
def POST(self, version='v2'): web.header('Content-Type', 'application/json') if version not in ('v2', 'v3'): return json.dumps({'ret': -999, 'msg': '版本错误!'}) print 'version=', version param = web.input(app_id='', session='', order_id='', total='', note='', sign='') if version == 'v2': if '' in (param.app_id, param.order_id, param.session, param.total, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) elif version == 'v3': if '' in (param.app_id, param.session, param.total, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) if web.ctx.has_key('environ'): client_ip = web.ctx.environ['REMOTE_ADDR'] else: return json.dumps({'ret': -5, 'msg': '无法取得客户端ip地址'}) uname = app_helper.app_logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign([ param.app_id, param.session, param.order_id, param.total, param.note ]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) #db_shop = db.base_shop.find_one({'_id':ObjectId(setting.default_shop)},{'name':1}) # 统一下单接口获取 prepay_id nonce_str = app_helper.my_rand(30) body = 'U掌柜app' trade_type = 'APP' if version == 'v2': order_id = '%s_%d' % (param.order_id.encode('utf-8'), int(time.time())) elif version == 'v3': if len(param.order_id) > 0: order_id = '%s_%d' % (param.order_id.encode('utf-8'), int(time.time())) print order_id else: # 生成order_id order_id = app_helper.get_new_order_id(version).encode( 'utf-8') print 'new order_id', order_id total_fee = param.total.encode('utf-8') para = [('appid', wx_appid), ('body', body), ('mch_id', mch_id), ('nonce_str', nonce_str), ('notify_url', notify_url), ('out_trade_no', order_id), ('spbill_create_ip', client_ip), ('total_fee', total_fee), ('trade_type', trade_type)] print para stringA = '&'.join('%s=%s' % i for i in para) stringSignTemp = '%s&key=%s' % (stringA, api_key) sign = hashlib.md5(stringSignTemp).hexdigest().upper() para_xml = '<xml>' \ '<appid>'+wx_appid+'</appid>' \ '<mch_id>'+mch_id+'</mch_id>' \ '<nonce_str>'+nonce_str+'</nonce_str>' \ '<sign>'+sign+'</sign>' \ '<body>'+body+'</body>' \ '<out_trade_no>'+order_id+'</out_trade_no>' \ '<total_fee>'+total_fee+'</total_fee>' \ '<spbill_create_ip>'+client_ip+'</spbill_create_ip>' \ '<notify_url>'+notify_url+'</notify_url>' \ '<trade_type>'+trade_type+'</trade_type>' \ '</xml>' print para_xml #return json.dumps({'ret' : 0, 'data' : 'here'}) urllib3.disable_warnings() pool = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.mch.weixin.qq.com/pay/unifiedorder' r = pool.urlopen('POST', url, body=para_xml) if r.status == 200: data = r.data print data if version == 'v2': # 记录微信商户订单号 db.order_app.update_one( {'order_id': param.order_id}, {'$set': { 'wx_out_trade_no': order_id }}) return json.dumps({'ret': 0, 'data': data}) elif version == 'v3': if len(param.order_id) > 0: db_order = db.order_app.find_one( {'order_id': param.order_id}) if db_order['status'] != 'DUE': print '============================== -100' return json.dumps({ 'ret': -100, 'msg': '订单状态变化,请确认' }) ret_json = checkout( version, uname, { 'session': param.session, 'order_id': param.order_id, 'shop_id': str(db_order['shop']), 'addr_id': db_order['address'][0], 'coupon_id': db_order['coupon'][0] if float(db_order['coupon_disc']) > 0 else '', 'cart': json.dumps(db_order['cart']), 'app_id': param.app_id, 'use_credit': '1' if float(db_order.get('use_credit', '0')) > 0 else '', #2015-11-19 }) if ret_json['ret'] < 0: # checkout 出错 return json.dumps({ 'ret': ret_json['ret'], 'msg': ret_json['msg'] }) if float(ret_json['data']['due']) != float( db_order.get('due3', db_order['due'])): # checkout后金额有变化,说明库存或优惠券有变化 db.order_app.update_one( {'order_id': param.order_id}, { '$set': { 'status': 'CANCEL' }, '$push': { 'history': (app_helper.time_str(), uname['uname'], '订单取消(微信支付)') } }) print '============================== -100' return json.dumps({ 'ret': -100, 'msg': '很抱歉,数据异常,订单已取消,请重新下单' }) # 可支付 db.order_app.update_one({'order_id': param.order_id}, { '$set': { 'wx_out_trade_no': order_id }, '$push': { 'history': (app_helper.time_str(), uname['uname'], '提交微信支付2') } }) return json.dumps({ 'ret': 0, 'order_id': param.order_id, 'data': data }) else: # 生成新订单 db_cart = db.app_user.find_one( {'uname': uname['uname']}, {'cart_order.%s' % param.session: 1}) new_order = dict(db_cart['cart_order'][param.session]) new_order['order_id'] = order_id new_order['status'] = 'DUE' new_order['user_note'] = param.note.strip() new_order['wx_out_trade_no'] = order_id new_order['history'] = [(app_helper.time_str(), uname['uname'], '提交微信支付')] ret_json = checkout( version, uname, { 'session': param.session, 'order_id': order_id, 'shop_id': str(new_order['shop']), 'addr_id': new_order['address'][0], 'coupon_id': new_order['coupon'][0] if float(new_order['coupon_disc']) > 0 else '', 'cart': json.dumps(new_order['cart']), 'app_id': param.app_id, 'use_credit': '1' if float(new_order.get('use_credit', '0')) > 0 else '', #2015-11-23 }) if ret_json['ret'] < 0: # checkout 出错 return json.dumps({ 'ret': ret_json['ret'], 'msg': ret_json['msg'] }) if float(ret_json['data']['due']) != float( new_order.get('due3', new_order['due'])): # checkout后金额有变化,说明库存或优惠券有变化 print '============================== -100' return json.dumps({ 'ret': -100, 'msg': '很抱歉,数据异常,请重新下单' }) db.order_app.insert_one(new_order) return json.dumps({ 'ret': 0, 'order_id': order_id, 'data': data }) else: return json.dumps({'ret': -1, 'data': r.status}) else: return json.dumps({'ret': -4, 'msg': '无效的session'})
def POST(self): web.header('Content-Type', 'application/json') param = web.input(app_id='', dev_id='', ver_code='', tick='', qqid='', nickname='', img_url='') if '' in (param.app_id, param.dev_id, param.ver_code, param.tick, param.qqid): return json.dumps({'ret': -2, 'msg': '参数错误'}) # 根据qqid检查用户是否存在 db_user = db.app_user.find_one({'qqid': param['qqid']}) if db_user == None: # 未注册,新建用户记录, new_set = { 'userid': '', # 用户id,未绑定为空 'qqid': param['qqid'], #'unionid' : param['unionid'], 'type': 4, # 1 电话号码用户, 2 微信app登录用户, 3 微信公众号用户, 4 QQ用户 'bind': 0, # 1 已绑定, 0 未绑定 'mice': 0, # 1 正常用户, 0 黑名单用户 'app_id': param.app_id, 'reg_time': app_helper.time_str(), 'last_status': int(time.time()), 'nickname': param.nickname, 'img_url': urllib.unquote_plus(param.img_url), } # 用户中心注册用户接口 db.app_user.update_one({'qqid': param['qqid']}, {'$set': new_set}, upsert=True) register = True else: # 更新app_id db.app_user.update_one({'qqid': param['qqid']}, { '$set': { 'app_id': param['app_id'], 'nickname': param.nickname, 'img_url': urllib.unquote_plus(param.img_url), 'last_status': int(time.time()), } }) register = False userid = db_user['userid'] if db_user else '' if_bind = (db_user['bind'] == 1) if db_user else False bound_tel = '' # 绑定的电话号码 user_role = 0 # 店员身份, 如果没绑定就不会有 if if_bind: r3 = db.app_user.find_one({'userid': userid, 'type': 1}) if r3: bound_tel = r3['uname'] user_role = r3.get('user_role', 0) # 生成session import os rand2 = os.urandom(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'userid': userid, 'uname': param.qqid, 'login': 1, 'ip': web.ctx.ip, 'attime': now, 'type': 4, 'bind': 1 if if_bind else 0, }) print 'if_bind', if_bind, bound_tel alert = False message = '' return json.dumps({ 'ret': 0, 'data': { 'session': session_id, 'bound_tel': bound_tel, 'if_bind': if_bind, # True表示已绑定手机号(和bind_enable的用处不一样) 'alert': alert, 'message': message, 'user_new': register, #是否为新用户 'user_role': user_role, } })
def POST(self): web.header('Content-Type', 'application/json') param = web.input(app_id='', session='', shop_id='', order_id='', addr_id='', coupon_id='', cart='', sign='') print param if '' in (param.app_id, param.session, param.shop_id, param.addr_id, param.cart, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) uname = app_helper.logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign([ param.app_id, param.session, param.order_id, param.shop_id, param.addr_id, param.coupon_id, param.cart ]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) # 记录版本信息 db.app_user.update_one({'uname': uname}, {'$set': { 'version': 'v1' }}) # mice 为黄牛手机号标志,mice==1不可以下单 2015-08-22 db_user = db.app_user.find_one( {'uname': uname}, #, 'mice':{'$ne':1}}, { 'coupon': 1, 'address': 1, 'credit': 1, 'app_id': 1, 'mice': 1 }) if db_user == None: # 不应该发生 return json.dumps({'ret': -9, 'msg': '未找到用户信息'}) # 检查mice, 排除白名单 if db_user.get('mice') == 1 and uname not in app_helper.WHITE_LIST: print 'mice !!!' return json.dumps({'ret': -9, 'msg': '未找到用户信息'}) app_id = db_user['app_id'] # 修改未付款的过期订单 db.order_app.update_many( { #'uname' : uname, 'status': 'DUE', 'deadline': { '$lt': int(time.time()) } }, {'$set': { 'status': 'TIMEOUT' }}) # 检查是否有新红包 #app_helper.check_hb(uname) # 先要核对送货地址是否在门店送货范围内!!!!!!! -- 需补充 # 查找shop db_shop = db.base_shop.find_one({'_id': ObjectId(param.shop_id)}) if db_shop == None: return json.dumps({'ret': -6, 'msg': 'shop_id错误'}) # 查询收货地址 address = None for i in db_user['address']: if i[0] == param.addr_id: address = list(i) break if address == None: return json.dumps({'ret': -7, 'msg': 'addr_id错误'}) ########################################################################### # 用收货电话检查黄牛 2015-08-22 db_recv = db.recv_tel.find_one({'tel': address[2]}) if db_recv: one_more = 0 if uname not in db_recv['unames']: # 补充疑似账号 db.recv_tel.update_one({'tel': address[2]}, {'$push': { 'unames': uname }}) one_more = 1 if len(db_recv['unames']) + one_more > 10: # 改为10,2015-10-12 # 发现 mice mice = 1 for b in db_recv['unames']: if b in app_helper.WHITE_LIST: # 过滤白名单相关号码 mice = 0 break db.app_user.update_many( {'uname': { '$in': db_recv['unames'] }}, {'$set': { 'mice': mice }}) db.app_user.update_many( {'openid': { '$in': db_recv['unames'] }}, {'$set': { 'mice': mice }}) if one_more == 1: db.app_user.update_one({'uname': uname}, {'$set': { 'mice': mice }}) if mice == 1: print '!!! mice:', address[ 2] #, uname, db_recv['unames'] return json.dumps({'ret': -9, 'msg': '黄牛下单1'}) else: db.recv_tel.insert_one({'tel': address[2], 'unames': [uname]}) print 'insert', address[2] # 用收货地址检查黄牛, 不准确,不能标注 2015-08-23 db_recv = db.recv_addr.find_one({'addr': address[3]}) if db_recv: one_more = 0 if uname not in db_recv['unames']: db.recv_addr.update_one({'addr': address[3]}, {'$push': { 'unames': uname }}) one_more = 1 if len(db_recv['unames']) + one_more > 10: # 改为10,2015-10-12 # 发现疑似mice,不标注,因为不确定 print '!!! maybe a mice:', address[3].encode( 'utf-8') #, uname, db_recv['unames'] else: db.recv_addr.insert_one({ 'addr': address[3], 'unames': [uname] }) #print 'insert', address[2] # 用app_id检查黄牛 appid_count = db.app_user.find({ 'app_id': app_id }, { '_id': 1 }).count() if appid_count > 10 and app_id.strip( ) != '': # app_id 可能为空,新绑定的用户 # 改为10,2015-10-12 # 发现 mice db_mice = db.app_user.find({'app_id': app_id}, {'uname': 1}) mice = [] for m in db_mice: if m['uname'] in app_helper.WHITE_LIST: # 过滤白名单 mice = [] break else: mice.append(m['uname']) db.app_user.update_many({'uname': { '$in': mice }}, {'$set': { 'mice': 1 }}) if mice != []: print '!!! mice by app_id: ', mice return json.dumps({'ret': -9, 'msg': '黄牛下单1'}) # 查黄牛-结束 ########################################################################### # 查找优惠券 # 未查到,则不使用优惠券 coupon = None for i in db_user['coupon']: if i[0] == param.coupon_id: coupon = list(i) break # 转换cart数据为json,应该有异常捕获 !!! cart = json.loads(param.cart) #print cart if len(cart) == 0: return json.dumps({'ret': -5, 'msg': '购物车无数据'}) if param.order_id == '': #cc = 1 #while cc!=None: # # 取得sku计数, 不与线下order共用 # db_sa = db.user.find_one_and_update( # {'uname' : 'settings'}, # {'$inc' : {'app_count' : 1}}, # {'app_count' : 1} # ) # order_id = 'n%06d' % db_sa['app_count'] # # 防止订单号重复 # cc = db.order_app.find_one({'order_id' : order_id},{'_id':1}) order_id = app_helper.get_new_order_id('v1') print 'new order_id', order_id else: order_id = param.order_id cc = db.order_app.find_one( { #'uname' : uname, # 防止app的bug,重复order_id 'order_id': order_id, }, { 'status': 1, }) if cc != None and cc[ 'status'] != 'DUE': # 检查订单状态,只有due才可以checkout print "BUG! order_id status" return json.dumps({'ret': -99, 'msg': '参数错误'}) # 订单状态:DUE, PAID, ONROAD, COMPLETED, CANCELED, FINISH # 默认运费 5元,免邮门槛 29元 order = { 'status': 'DUE', 'uname': uname, 'shop': db_shop['_id'], 'user': uname, 'order_id': order_id, 'order_source': app_helper.get_devive_type(param.app_id), 'address': address, # 收货地址 'coupon': coupon, # 使用的优惠券 'cart': [], 'cost': '0.00', # 成本合计,参考 'total': '0.00', # 价格小计,加项 'coupon_disc': '0.00', # 优惠券抵扣,减项 'first_disc': '0.00', # 首单立减, 减项 'delivery_fee': '0.00', # 运费,加项 'due': '0.00', # 应付价格 'uname_id': db_user['_id'], # for processor 'next_status': '', 'lock': 0, 'man': 0, 'retry': 0, 'comment': '', 'b_time': int(time.time()), 'e_time': int(time.time()), 'deadline': int(time.time() + 60 * 15), } # 统计旧订单数,为0则是首单 2015-09-29 old_order_num = db.order_app.find( { 'user': uname, 'status': { '$nin': ['DUE', 'TIMEOUT', 'CANCEL'] } }, { '_id': 1 }).count() # item = { # “product_id” : “k000011”, # “num” : “5”, # } # 应该只有 k-prod cart_to_return = [] cate_001 = 0 b3_sku = 0 for item in cart: # sku db_sku = db.sku_store.find_one( {'product_id': item['product_id']}, { 'app_title': 1, 'is_onsale': 1, 'special_price': 1, 'ref_price': 1, 'maximun': 1, 'list_in_app': 1, }) if db_sku == None: # 应该不会发生 print 'Error: db_sku==None' continue if db_sku['list_in_app'] == -3: # B3 整箱预售 # -3 不启动B3销售 r = db.inventory.find_one( # 线上销售要检查库存 { 'product_id' : item['product_id'], 'list_in_app' : {'$ne' : 0}, 'shop' : ObjectId(setting.B3_shop), }, { 'cost_price' : 1, 'ref_prod_id' : 1, 'price' : 1, 'sku' : 1, 'num' : 1, 'category' : 1, 'first_order' : 1 } ) b3_sku += 1 else: r = db.inventory.find_one( # 线上销售要检查库存 { 'product_id' : item['product_id'], 'list_in_app' : {'$ne' : 0}, 'shop' : db_shop['_id'], }, { 'cost_price' : 1, 'ref_prod_id' : 1, 'price' : 1, 'sku' : 1, 'num' : 1, 'category' : 1, 'first_order' : 1 } ) if r: # 如果库存数据中没此sku,会忽略掉,此情况应该不会发生 new_num = int(item['num']) new_num = new_num if new_num <= r['num'] else r['num'] new_num = max(0, new_num) # 发现过小于零的情况,微信 # 检查是不是 001 (水果) 分类 if r['category'] == '001': cate_001 += 1 # 检查是否限购 if db_sku['maximun'] > 0: ''' # 每日限购,生成当天的时间tick tday = app_helper.time_str(format=1) begin_d = '%s 00:00:00' % tday end_d = '%s 23:59:59' % tday begin_t = int(time.mktime(time.strptime(begin_d,"%Y-%m-%d %H:%M:%S"))) end_t = int(time.mktime(time.strptime(end_d,"%Y-%m-%d %H:%M:%S"))) print begin_d, end_d, begin_t, end_t # 检查时间段内购买记录 c = db.order_app.find({ 'uname' : uname, 'order_id' : {'$ne':order_id}, 'status' : {'$ne':'TIMEOUT'}, 'cart.product_id' : item['product_id'], '$and' : [{'b_time' : {'$gt' : begin_t}}, {'b_time' : {'$lt' : end_t}}], }, {'_id':1}).count() print 'findings: ',c if c>0: # 限购商品只允许购买1次 new_num=0 else: new_num=min(new_num, db_sku['maximun']) print 'limit : ',new_num ''' # 每单限购 if new_num > db_sku['maximun']: new_num = db_sku['maximun'] item['num'] = '%d' % new_num # 防止iOS闪退!!! print 'limit : ', new_num ''' # 买一送一 每单限购1件 if item['product_id'] in app_helper.buy_1_give_1: #new_num=min(new_num, 1) #print 'buy 1 give 1 limit : ',new_num new_item = { 'product_id' : item['product_id'], 'num' : '%d' % new_num, 'num2' : new_num, 'price' : r['price'], 'title' : db_sku['app_title'], } else: ''' # 首单可见商品,非首单用户 2015-09-29 if r.has_key('first_order') and r[ 'first_order'] == 1 and old_order_num > 0: # 非首单用户,不让购买,比较生硬 new_num = 0 item['num'] = '%d' % new_num # 防止iOS闪退!!! new_item = { 'product_id': item['product_id'], 'num': item['num'], 'num2': new_num, 'price': r['price'], 'title': db_sku['app_title'], } # 是否有优惠价格 if db_sku['is_onsale']==1 and \ float(db_sku['special_price'])<float(r['price']): # 优惠价格比门店价格低 new_item['price'] = db_sku['special_price'] # 计算总价 item_price = round(new_num * float(new_item['price']), 2) new_item['price'] = '%.2f' % item_price cart_to_return.append(new_item) # 返回到app的cart不包含cost cost_price = r['cost_price'] #if item[0][0]=='w': # w-prod 信息都用 u-prod的替换 # new_item['product_id'] = r['ref_prod_id'] # new_item['w_id'] = item[0] # # 查询成本, 从对应u-prod当前成本 # r2 = db.inventory.find_one({ # u-prod # 'shop' : db_shop['shop'], # 'product_id' : r['ref_prod_id'], # }, {'cost_price':1}) # cost_price = r2['cost_price'] # 计算成本 item_cost = round(new_num * float(cost_price), 2) new_item['cost'] = '%.2f' % item_cost # 加入cart order['cart'].append(new_item) # 累计售价和成本 order['total'] = '%.2f' % (float(order['total']) + item_price) order['cost'] = '%.2f' % (float(order['cost']) + item_cost) else: # 店内未找到库存, !!!应该不会发生 new_item = { 'product_id': item['product_id'], 'num': item['num'], 'num2': 0, 'price': '0.00', 'cost': '0.00', 'title': db_sku['app_title'], } cart_to_return.append(new_item) # 返回到app的cart不包含cost order['cart'].append(new_item) tt = float(order['total']) if tt > 0: # 免邮门槛 #if tt<29: # 免邮门槛 29 if tt < app_helper.free_delivery: # 免邮门槛 order[ 'delivery_fee'] = '%.2f' % app_helper.delivery_fee # 运费5元 ''' # 首单立减 first_promote元, 商品总额大于 first_promote_threshold元 cut_now = app_helper.first_promote # if cate_001>0 and (tt+float(order['delivery_fee']))>=app_helper.first_promote_threshold and \ db.order_app.find({'user':uname, 'status':{'$nin':['DUE','TIMEOUT','CANCEL']}},{'_id':1}).count()==0: order['first_disc'] = '%.2f' % cut_now ''' # 首单立减 first_promote元, 商品总额大于 first_promote_threshold元 if cate_001 > 0 and old_order_num == 0: # 符合首单条件,且有一个水果商品 print '首单' if str(db_shop['_id']) in app_helper.first_promote2_shop and \ (tt+float(order['delivery_fee']))>=app_helper.first_promote2_threshold: # 站点落在 指定站点范围内,使用首单立减2 print '首单立减 - 指定站点' order[ 'first_disc'] = '%.2f' % app_helper.first_promote2 elif (tt + float(order['delivery_fee']) ) >= app_helper.first_promote_threshold: # 其他站点使用首单立减1 print '首单立减' order['first_disc'] = '%.2f' % app_helper.first_promote # 优惠券, 检查有效期, 优惠券门槛为10元 if float(order['first_disc'])==0.0 and coupon!=None and \ coupon[3]==1 and app_helper.time_str(format=1)<=coupon[1]: if len(coupon ) > 5 and coupon[5] == 'apple' and cate_001 < 1: # 水果券,但没有水果 2015-09-29 print '水果券没水果' order['coupon'] = None elif len(coupon) > 5 and coupon[5] == 'b3' and b3_sku < 1: # 整箱券,但没有整箱 2015-10-18 print '整箱券没整箱' order['coupon'] = None else: if len(coupon) > 4: # (id, 有效期, 金额, 是否已用, 门槛) 2015-09-27 # 有门槛信息,使用优惠券门槛信息 if (tt + float(order['delivery_fee'])) < coupon[4]: order['coupon'] = None else: order['coupon_disc'] = coupon[2] else: # 使用默认条件 if float(coupon[2]) == 6.0 and ( tt + float(order['delivery_fee'])) < 29.9: order['coupon'] = None elif float(coupon[2]) == 9.0 and ( tt + float(order['delivery_fee'])) < 39.9: order['coupon'] = None elif (tt + float(order['delivery_fee'])) < 14.9: order['coupon'] = None else: order['coupon_disc'] = coupon[2] else: order['coupon'] = None # 计算应付:价格合计 - 优惠券 - 首单立减 + 运费 print(tt + float(order['delivery_fee']) - float(order['coupon_disc']) - float(order['first_disc'])) print tt, float(order['delivery_fee']), float( order['coupon_disc']), float(order['first_disc']) order['due'] = '%.2f' % (tt + float(order['delivery_fee']) - float(order['coupon_disc']) - float(order['first_disc'])) if float(order['due']) <= 0: order['due'] = '0.10' # 如果没有,则insert #db.order_app.replace_one({'order_id':order_id}, order, upsert=True) db.order_app.update_one({'order_id': order_id}, { '$set': order, '$push': { 'history': (app_helper.time_str(), uname, '提交结算') } }, upsert=True) ret_json = { # 返回结果,实际有库存的结果, 'ret': 0, 'data': { 'order_id': order['order_id'], 'shop_id': str(order['shop']), 'shop': db_shop['name'], # 可能会变,如果地址与门店不匹配的时候 'addr_id': address[0], 'cart_num': len(order['cart']), 'cart': cart_to_return, 'total': order['total'], 'coupon': coupon[0] if order['coupon'] else '', 'coupon_disc': order['coupon_disc'], 'first_disc': order['first_disc'], 'delivery_fee': order['delivery_fee'], 'due': order['due'], 'credit': '%.2f' % db_user.get('credit', 0.0) } } print ret_json return json.dumps(ret_json) else: return json.dumps({'ret': -4, 'msg': '无效的session'})
def user_reg(param): number = param.mobile.strip() if len(number) < 11 or (not number.isdigit()): return json.dumps({'ret': -10, 'msg': '手机号码格式错误'}) if number in app_helper.BLOCK_LIST: return json.dumps({'ret': -10, 'msg': '手机号码错误'}) # 随机码 rand = app_helper.my_rand(base=1) # 检查用户是否已注册 db_user = db.app_user.find_one({'uname': number}) if db_user == None: # 未注册,新建用户记录 userid = app_helper.gen_new_userid() new_set = { 'userid': userid, # 用户id,用于唯一标识 'uname': number, 'type': 1, # 1 电话号码用户, 2 微信app登录用户, 3 微信公众号用户 'bind': 1, # 1 已绑定, 0 未绑定, 电话用户本身就认为是绑定的 'mice': 0, # 1 正常用户, 0 黑名单用户 'app_id': param.app_id, 'reg_time': app_helper.time_str(), 'last_status': int(time.time()), 'reg_ok': 0, } # 用户中心注册用户接口 db.app_user.update_one({'userid': userid}, {'$set': new_set}, upsert=True) else: # 更新app_id #userid = db_user['userid'] #db.app_user.update_one({'userid':db_user['userid']},{'$set':{ # 'app_id' : param.app_id, # 'last_status' : int(time.time()), #}}) if db_user.get('reg_ok') == 1: return json.dumps({'ret': -6, 'msg': '手机号码已注册'}) userid = db_user['userid'] # 生成 session ------------------ rand2 = os.urandom(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'userid': userid, 'uname': number, 'login': 0, 'rand': rand, 'ip': web.ctx.ip, 'attime': now, 'type': 1, 'pwd_fail': 0, 'bind': 1, # 电话用户本身就认为是绑定的 }) # ------------------------------- #发送短信验证码 if number not in app_helper.INNER_NUM.keys( ): # 内部号码不发短信,2015-12-22, gt rr = sms.send_rand(number, rand, True) # 测试不发校验码 if rr is None: return json.dumps({'ret': -11, 'msg': '发送太频繁,稍后再试'}) # 返回 return json.dumps({ 'ret': 0, 'data': { 'session': session_id, } })
def checkout(version, uname, param): print param # mice 为黄牛手机号标志,mice==1不可以下单 2015-08-22 db_user = db.app_user.find_one( {'uname': uname['uname']}, #, 'mice':{'$ne':1}}, { 'coupon': 1, 'address': 1, 'credit': 1, 'app_id': 1, 'mice': 1 }) if db_user == None: # 不应该发生 return {'ret': -9, 'msg': '未找到用户信息'} # 检查mice, 排除白名单 if db_user.get( 'mice') == 1 and uname['uname'] not in app_helper.WHITE_LIST: print 'mice !!!' return {'ret': -9, 'msg': '未找到用户信息'} app_id = db_user['app_id'] # 修改为付款的过期订单 r = db.order_app.update_many( { #'uname' : {'$in':uname.values()}, 'status': 'DUE', 'deadline': { '$lt': int(time.time()) } }, {'$set': { 'status': 'TIMEOUT' }}) # 查找shop db_shop = db.base_shop.find_one({'_id': ObjectId(param['shop_id'])}) if db_shop == None: return {'ret': -6, 'msg': 'shop_id错误'} # 查询收货地址 address = None for i in db_user['address']: if i[0] == param['addr_id']: address = list(i) break if address == None: return {'ret': -7, 'msg': 'addr_id错误'} # 获得 收货地址 坐标 if len(address) > 5: # 使用已有的gps地址 loc = address[5] else: ret, loc = lbs.addr_to_loc(address[3].encode('utf-8')) if ret < 0: # 重试一次 ret, loc = lbs.addr_to_loc(address[3].encode('utf-8')) if ret < 0: loc = {'lat': 0, 'lng': 0} print loc # 多边形检查 poly_shop = lbs.check_in_poly((loc['lat'], loc['lng']), db_shop.get('poly_xy', [])) if poly_shop == None: return {'ret': -6, 'msg': 'shop_id错误'} ########################################################################### # 用收货电话检查黄牛 2015-08-22 db_recv = db.recv_tel.find_one({'tel': address[2]}) if db_recv: one_more = 0 if uname['uname'] not in db_recv['unames']: # 补充疑似账号 db.recv_tel.update_one({'tel': address[2]}, {'$push': { 'unames': uname['uname'] }}) one_more = 1 if len(db_recv['unames']) + one_more > 10: # 改为10,2015-10-12 # 发现 mice mice = 1 for b in db_recv['unames']: if b in app_helper.WHITE_LIST: # 过滤白名单相关号码 mice = 0 break db.app_user.update_many({'uname': { '$in': db_recv['unames'] }}, {'$set': { 'mice': mice }}) db.app_user.update_many({'openid': { '$in': db_recv['unames'] }}, {'$set': { 'mice': mice }}) if one_more == 1: db.app_user.update_one({'uname': uname['uname']}, {'$set': { 'mice': mice }}) if mice == 1: print '!!! mice:', address[ 2] #, uname['uname'], db_recv['unames'] return {'ret': -9, 'msg': '黄牛下单1'} else: db.recv_tel.insert_one({'tel': address[2], 'unames': [uname['uname']]}) #print 'insert', address[2] # 用收货地址检查黄牛, 不准确,不能标注 2015-08-23 db_recv = db.recv_addr.find_one({'addr': address[3]}) if db_recv: one_more = 0 if uname['uname'] not in db_recv['unames']: db.recv_addr.update_one({'addr': address[3]}, {'$push': { 'unames': uname['uname'] }}) one_more = 1 if len(db_recv['unames']) + one_more > 10: # 改为10,2015-10-12 # 发现疑似mice,不标注,因为不确定 print '!!! maybe a mice:', address[3].encode( 'utf-8') #, uname['uname'], db_recv['unames'] else: db.recv_addr.insert_one({ 'addr': address[3], 'unames': [uname['uname']] }) #print 'insert', address[2] # 用app_id检查黄牛 appid_count = db.app_user.find({'app_id': app_id}, {'_id': 1}).count() if appid_count > 10 and app_id.strip( ) != '': # app_id 可能为空,新绑定的用户 # 改为10,2015-10-12 # 发现 mice db_mice = db.app_user.find({'app_id': app_id}, {'uname': 1}) mice = [] for m in db_mice: if m['uname'] in app_helper.WHITE_LIST: # 过滤白名单 mice = [] break else: mice.append(m['uname']) db.app_user.update_many({'uname': { '$in': mice }}, {'$set': { 'mice': 1 }}) if mice != []: print '!!! mice by app_id: ', mice return {'ret': -9, 'msg': '黄牛下单1'} # 查黄牛-结束 ########################################################################### # 查找优惠券 # 未查到,则不使用优惠券 coupon = None for i in db_user['coupon']: if i[0] == param['coupon_id']: coupon = list(i) break # 转换cart数据为json,应该有异常捕获 !!! #print param['cart'] cart = json.loads(param['cart']) #print cart if len(cart) == 0: return {'ret': -5, 'msg': '购物车无数据'} if version == 'v2': # v3 不在这生成订单号 if param['order_id'] == '': #cc = 1 #while cc!=None: # # 取得sku计数, 不与线下order共用 # db_sa = db.user.find_one_and_update( # {'uname' : 'settings'}, # {'$inc' : {'app_count' : 1}}, # {'app_count' : 1} # ) # order_id = 'n%06d%s' % (db_sa['app_count'], setting.order_fuffix) # # 防止订单号重复 # cc = db.order_app.find_one({'order_id' : order_id},{'_id':1}) order_id = app_helper.get_new_order_id(version) print 'new order_id', order_id else: order_id = param['order_id'] cc = db.order_app.find_one( { #'uname' : {'$in':uname.values()}, # 防止app的bug,重复order_id 'order_id': order_id, }, { 'status': 1, }) if cc != None and cc['status'] != 'DUE': # 检查订单状态,只有due才可以checkout print "BUG! order_id status" return {'ret': -99, 'msg': '订单状态错误'} # 订单状态:DUE, PAID, ONROAD, COMPLETED, CANCELED, FINISH # 默认运费 5元,免邮门槛 29元 order = { 'status': 'DUE', 'uname': uname['uname'], 'shop': db_shop['_id'], 'user': uname['uname'], 'order_id': order_id if version == 'v2' else '', 'order_source': app_helper.get_devive_type(param['app_id']), 'address': address, # 收货地址 'coupon': coupon, # 使用的优惠券 'cart': [], 'cost': '0.00', # 成本合计,参考 'total': '0.00', # 价格小计,加项 'coupon_disc': '0.00', # 优惠券抵扣,减项 'first_disc': '0.00', # 首单立减, 减项 'delivery_fee': '0.00', # 运费,加项 'due': '0.00', # 应付总金额 2015-11-24 'openid': uname['openid'], 'app_uname': uname['uname'], 'uname_id': db_user['_id'], 'type': 'HOUR', # 订单类型, 2015-11-19 # for processor 'next_status': '', 'lock': 0, 'man': 0, 'retry': 0, 'comment': '', 'b_time': int(time.time()), 'e_time': int(time.time()), 'deadline': int(time.time() + 60 * 15), 'poly_shop': 1 if poly_shop else 0, # 是否匹配到门店 2015-10-18 'credit_total': '0.00', # 余额支付金额 2015-11-24 'wxpay_total': '0.00', # 微信支付金额 'alipay_total': '0.00', # 支付宝支付金额 'use_credit': '0.00', # 部分支付时,余额支付金额 'due3': '0.00', # 第3方应付金额 use_credit + due3 = due } # 统计旧订单数,为0则是首单 2015-09-29 old_order_num = db.order_app.find( { 'user': { '$in': uname.values() }, 'status': { '$nin': ['DUE', 'TIMEOUT', 'CANCEL'] } }, { '_id': 1 }).count() # item = { # “product_id” : “k000011”, # “num” : “5”, # } # 应该只有 k-prod cart_to_return = [] cart_to_return_b3 = [] cate_001 = 0 b3_sku = 0 all_sku = 0 num_change = 0 buy_limit = 0 only_one = 0 for item in cart: is_b3 = False # sku db_sku = db.sku_store.find_one({'product_id': item['product_id']}, { 'app_title': 1, 'is_onsale': 1, 'special_price': 1, 'ref_price': 1, 'maximun': 1, 'list_in_app': 1, }) if db_sku == None: # 应该不会发生 print 'Error: db_sku==None' continue all_sku += 1 if db_sku['list_in_app'] == -3: # B3 整箱预售 # 不启动B3 2015-10-27 r = db.inventory.find_one( # 线上销售要检查库存 { 'product_id' : item['product_id'], 'list_in_app' : {'$ne' : 0}, 'shop' : ObjectId(setting.B3_shop), }, { 'cost_price' : 1, 'ref_prod_id' : 1, 'price' : 1, 'sku' : 1, 'num' : 1, 'category' : 1, 'first_order' : 1 } ) b3_sku += 1 is_b3 = True # 标记是B3商品, v3 elif poly_shop: # 门店库存 r = db.inventory.find_one( # 线上销售要检查库存 { 'product_id' : item['product_id'], 'list_in_app' : {'$ne' : 0}, 'shop' : db_shop['_id'], }, { 'cost_price':1, 'ref_prod_id':1, 'price':1, 'sku':1, 'num':1, 'category':1, 'first_order':1 } ) else: # 不在送货范围 r = None if r: # 如果库存数据中没此sku,会忽略掉,此情况应该不会发生 new_num = int(item['num']) new_num = new_num if new_num <= r['num'] else r['num'] new_num = max(0, new_num) # 发现过小于零的情况,微信 # 检查是不是 001 (水果) 分类 if r['category'] == '001': cate_001 += 1 # 检查是否限购 if db_sku['maximun'] > 0: ''' # 每日限购,生成当天的时间tick tday = app_helper.time_str(format=1) begin_d = '%s 00:00:00' % tday end_d = '%s 23:59:59' % tday begin_t = int(time.mktime(time.strptime(begin_d,"%Y-%m-%d %H:%M:%S"))) end_t = int(time.mktime(time.strptime(end_d,"%Y-%m-%d %H:%M:%S"))) print begin_d, end_d, begin_t, end_t # 检查时间段内购买记录 c = db.order_app.find({ 'uname' : {'$in':uname.values()}, 'order_id' : {'$ne':order_id}, 'status' : {'$ne':'TIMEOUT'}, 'cart.product_id' : item['product_id'], '$and' : [{'b_time' : {'$gt' : begin_t}}, {'b_time' : {'$lt' : end_t}}], }, {'_id':1}).count() print 'findings: ',c if c>0: # 限购商品只允许购买1次 new_num=0 buy_limit += 1 else: new_num=min(new_num, db_sku['maximun']) print 'limit : ',new_num ''' # 每单限购 if new_num > db_sku['maximun']: new_num = db_sku['maximun'] print 'limit : ', new_num # 首单可见商品,非首单用户 2015-09-30 if r.has_key('first_order' ) and r['first_order'] == 1 and old_order_num > 0: # 非首单用户,不让购买,还是有人能买到,靠! new_num = 0 # v3 检查是否是互斥商品 if version == 'v3' and item['product_id'] in app_helper.only_one: if only_one > 0: # 已有互斥商品,此商品清零 new_num = 0 else: only_one += 1 # v3 检查是否买X送Y if version == 'v3' and item[ 'product_id'] in app_helper.buy_X_give_Y.keys(): numX = app_helper.buy_X_give_Y[item['product_id']][0] numY = app_helper.buy_X_give_Y[item['product_id']][1] #new_num = int(item['num']) new_num_give = int(new_num / numX) * numY new_num = new_num if new_num + new_num_give <= r[ 'num'] else int(r['num'] / (numX + numY)) * numX new_num = max(0, new_num) # 预防小于零的情况 new_num_give = int(new_num / numX) * numY # 更新赠品数量 new_item = { 'product_id': item['product_id'], 'num': item['num'], 'num2': new_num, 'price': r['price'], 'title': db_sku['app_title'], } # v3 买X送Y数量 if version == 'v3': if item['product_id'] in app_helper.buy_X_give_Y.keys(): new_item['numyy'] = new_num_give else: new_item['numyy'] = 0 if int(new_num) != int(item['num']): num_change += 1 # 是否有优惠价格 if db_sku['is_onsale']==1 and \ float(db_sku['special_price'])<float(r['price']): # 优惠价格比门店价格低 new_item['price'] = db_sku['special_price'] # 计算总价 item_price = round(new_num * float(new_item['price']), 2) new_item['price'] = '%.2f' % item_price if version == 'v3' and is_b3: cart_to_return_b3.append(new_item) else: cart_to_return.append(new_item) # 返回到app的cart不包含cost cost_price = r['cost_price'] #if item[0][0]=='w': # w-prod 信息都用 u-prod的替换 # new_item['product_id'] = r['ref_prod_id'] # new_item['w_id'] = item[0] # # 查询成本, 从对应u-prod当前成本 # r2 = db.inventory.find_one({ # u-prod # 'shop' : db_shop['shop'], # 'product_id' : r['ref_prod_id'], # }, {'cost_price':1}) # cost_price = r2['cost_price'] # 计算成本 item_cost = round(new_num * float(cost_price), 2) new_item['cost'] = '%.2f' % item_cost # 加入cart order['cart'].append(new_item) # 累计售价和成本 order['total'] = '%.2f' % (float(order['total']) + item_price) order['cost'] = '%.2f' % (float(order['cost']) + item_cost) else: # 店内未找到库存, !!!应该不会发生 new_item = { 'product_id': item['product_id'], 'num': item['num'], 'num2': 0, 'price': '0.00', 'cost': '0.00', 'title': db_sku['app_title'], } cart_to_return.append(new_item) # 返回到app的cart不包含cost order['cart'].append(new_item) # 记录判断数量变化 if int(new_item['num2']) != int(item['num']): num_change += 1 tt = float(order['total']) if tt > 0: # 免邮门槛 if str(order['shop']) in app_helper.delivery_by_shop.keys(): delivery_fee = app_helper.delivery_by_shop[str( order['shop'])]['delivery_fee'] free_delivery = app_helper.delivery_by_shop[str( order['shop'])]['free_delivery'] else: delivery_fee = app_helper.delivery_fee free_delivery = app_helper.free_delivery #if tt<29: # 免邮门槛 29 if tt < free_delivery: # 免邮门槛 order['delivery_fee'] = '%.2f' % delivery_fee # 运费5元 # 首单立减 first_promote元, 商品总额大于 first_promote_threshold元 if cate_001 > 0 and old_order_num == 0: # 符合首单条件,且有一个水果商品 print '首单' if str(db_shop['_id']) in app_helper.first_promote2_shop and \ (tt+float(order['delivery_fee']))>=app_helper.first_promote2_threshold: # 站点落在 指定站点范围内,使用首单立减2 print '首单立减 - 指定站点' order['first_disc'] = '%.2f' % app_helper.first_promote2 elif (tt + float(order['delivery_fee']) ) >= app_helper.first_promote_threshold: # 其他站点使用首单立减1 print '首单立减' order['first_disc'] = '%.2f' % app_helper.first_promote # 优惠券, 检查有效期, 优惠券门槛为10元 if float(order['first_disc'])==0.0 and coupon!=None and \ coupon[3]==1 and app_helper.time_str(format=1)<=coupon[1]: print '检查抵用券' if len(coupon) > 5 and coupon[5] == 'apple' and cate_001 < 1: # 水果券,但没有水果 2015-09-29 print '水果券没水果' order['coupon'] = None elif len(coupon) > 5 and coupon[5] == 'b3' and b3_sku < 1: # 整箱券,但没有整箱 2015-10-18 print '整箱券没整箱' order['coupon'] = None else: if len(coupon) > 4: # (id, 有效期, 金额, 是否已用, 门槛) 2015-09-27 # 有门槛信息,使用优惠券门槛信息 if (tt + float(order['delivery_fee'])) < coupon[4]: order['coupon'] = None else: order['coupon_disc'] = coupon[2] else: # 使用默认条件 if float(coupon[2]) == 6.0 and ( tt + float(order['delivery_fee'])) < 29.9: order['coupon'] = None elif float(coupon[2]) == 9.0 and ( tt + float(order['delivery_fee'])) < 39.9: order['coupon'] = None elif (tt + float(order['delivery_fee'])) < 14.9: order['coupon'] = None else: order['coupon_disc'] = coupon[2] else: order['coupon'] = None # 计算应付:价格合计 - 优惠券 - 首单立减 + 运费 print(tt + float(order['delivery_fee']) - float(order['coupon_disc']) - float(order['first_disc'])) print tt, float(order['delivery_fee']), float( order['coupon_disc']), float(order['first_disc']) order['due'] = '%.2f' % (tt + float(order['delivery_fee']) - float( order['coupon_disc']) - float(order['first_disc'])) # 不能是负的, 要付一点 if float(order['due']) <= 0: order['due'] = '0.10' # 是否使用余额(部分)支付, 2015-11-19 if param.has_key('use_credit') and param['use_credit'] == '1': # 使用余额 my_due = float(order['due']) my_credit = db_user.get('credit', 0.0) if my_credit > my_due: order['due3'] = '0.00' order['use_credit'] = '%.2f' % my_due else: order['due3'] = '%.2f' % (my_due - my_credit) order['use_credit'] = '%.2f' % my_credit else: order['use_credit'] = '0.00' order['due3'] = order['due'] # 准备可用的优惠券 2015-09-11 coupon_list = [] for i in db_user['coupon']: if app_helper.time_str(format=1) > i[1]: # 过期抵用券 continue elif i[3] != 1: continue # 检查优惠券条件 b3_sku if tt > 0 and float(order['first_disc']) == 0.0: if len(i) > 5 and i[5] == 'apple' and cate_001 < 1: # 水果券没水果 continue if len(i) > 5 and i[5] == 'b3' and b3_sku < 1: # 整箱券没整箱 2015-10-18 continue if len(i) > 4: # 带门槛优惠券 if (tt + float(order['delivery_fee'])) < i[4]: continue else: # 过滤不符合条件的优惠券 if float(i[2]) == 6.0 and ( tt + float(order['delivery_fee'])) < 29.9: continue elif float(i[2]) == 9.0 and ( tt + float(order['delivery_fee'])) < 39.9: continue elif (tt + float(order['delivery_fee'])) < 14.9: continue coupon_list.append({ 'id': i[0], 'valid': i[1], 'cash': i[2], 'status': 'unused', 'msg1': '条件1', 'msg2': '条件2', }) coupon_list = quick(coupon_list) # 如果没有,则insert #db.order_app.replace_one({'order_id':order_id}, order, upsert=True) if version == 'v2': db.order_app.update_one({'order_id': order_id}, { '$set': order, '$push': { 'history': (app_helper.time_str(), uname['uname'], '提交结算') } }, upsert=True) elif version == 'v3': db.app_user.update_one( {'uname': uname['uname']}, {'$set': { 'cart_order.%s' % param['session']: order }}) # 提示信息 #print all_sku, b3_sku if poly_shop == False: msg_alert = True if b3_sku > 0: if all_sku > b3_sku: #message = '很抱歉,普通商品无法配送到当前地址,商品已更新' #,整箱预售商品可正常购买' msg_alert = False message = '' else: # 只有 b3 商品时不提醒 msg_alert = False message = '' else: message = '很抱歉,收货地址不在配送范围内,购物车商品已清空' else: if num_change > 0: msg_alert = True message = '库存不足,已更新商品数量,请查看' elif buy_limit > 0: msg_alert = True message = '部分商品限购,已更新商品数量,请查看' else: msg_alert = False message = '' if version == 'v2': ret_json = { # 返回结果,实际有库存的结果, 'ret': 0, 'data': { 'order_id': order['order_id'], 'shop_id': str(order['shop']), 'shop': db_shop['name'], # 可能会变,如果地址与门店不匹配的时候 'addr_id': address[0], 'cart_num': len(order['cart']), 'cart': cart_to_return, 'total': order['total'], 'coupon_list': coupon_list, # 可用的优惠券 'coupon': coupon[0] if order['coupon'] else '', 'coupon_disc': order['coupon_disc'], 'first_disc': order['first_disc'], 'delivery_fee': order['delivery_fee'], 'due': order['due'], 'credit': '%.2f' % db_user.get('credit', 0.0), 'alert': msg_alert, 'message': message, } } elif version == 'v3': hh = time.localtime().tm_hour if hh >= 9 and hh < 20: alert_title = False cart_title = '' else: alert_title = True if hh >= 20 and hh <= 23: cart_title = '目前是掌柜打烊时间,预计明日9点送出' else: cart_title = '目前是掌柜打烊时间,预计今日9点送出' if b3_sku > 0: if hh < 16: # 明天 tomorrow_tick = int(time.time()) + 3600 * 24 tomorrow = time.strftime("%m月%d日", time.localtime(tomorrow_tick)) cart_title_b3 = '以下预售商品,预计明天%s送达' % tomorrow else: # 后天 the_day_after_tick = int(time.time()) + 3600 * 24 * 2 the_day_after = time.strftime( "%m月%d日", time.localtime(the_day_after_tick)) cart_title_b3 = '以下预售商品,预计后天%s送达' % the_day_after else: cart_title_b3 = '' ret_json = { # 返回结果,实际有库存的结果, 'ret': 0, 'data': { 'shop_id': str(order['shop']), 'shop': db_shop['name'], # 可能会变,如果地址与门店不匹配的时候 'addr_id': address[0], 'cart_num': len(order['cart']), 'cart': cart_to_return, 'cart_b3': cart_to_return_b3, 'total': order['total'], 'coupon_list': coupon_list, # 可用的优惠券 'coupon': coupon[0] if order['coupon'] else '', 'coupon_disc': order['coupon_disc'], 'first_disc': order['first_disc'], 'delivery_fee': order['delivery_fee'], 'due': order['due3'], # 返回的事第3方需支付的金额 2015-11-24 'use_credit': order['use_credit'], # 使用余额的金额 2015-11-19 'credit': '%.2f' % db_user.get('credit', 0.0), 'alert': msg_alert, 'message': message, 'alert_title': alert_title, 'cart_title': cart_title, 'alert_title_b3': True, 'cart_title_b3': cart_title_b3, } } print ret_json return ret_json
def init_job(code, need_more_data=False, parent=None, auth_code=''): print '----> MIGIC CODE:', code if code == '': #return render.info('参数错误',goto='/') # info页面要做微信端优化 #raise web.seeother('/wx/init_fair') if need_more_data: return None, None, 0, 0 else: return None if len(code) < 20: # 小于20说明是自定义code,如果不在列表里,则拒绝 2020-04-09 if code in CODE_MIGIC.keys(): # 用于非微信环境进入 openid = code else: raise web.Unauthorized( 'Unauthorized visit.') # 这应该会显示 not found 2020-04-09 else: urllib3.disable_warnings() http = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' \ 'appid=%s&' \ 'secret=%s&' \ 'code=%s&' \ 'grant_type=authorization_code' % \ (wx_appid, wx_secret, code, ) r = http.request('GET', url) if r.status == 200: data = r.data t = json.loads(data) #print t http.clear() if t.has_key('openid'): openid = t['openid'] else: #print '===========Error==============', data, wx_secret, wx_appid if need_more_data: return None, None, 0, 0 else: return None else: http.clear() if need_more_data: return None, None, 0, 0 else: return None # 取得ticket ticket = get_ticket() if ticket == '': print 'get ticket fail!' #raise web.seeother('/wx/init_fair') #return None ticket = get_ticket(True) uname = '' # 检查用户是否已注册 #db_user = db.app_user .find_one({'openid':openid}) db_user = app_user_helper.get_user_info(openid, q_type='openid') is_new_user = 0 is_our_fan = True if db_user == None: # 未注册,新建用户记录 is_new_user = 1 # 用户基本信息 info = get_info(openid) if info.has_key('errcode'): get_ticket(True) info = get_info(openid) print info unionid = info.get('unionid', '') coupon = [] new_set = { 'openid': openid, 'unionid': unionid, 'region_id': setting.region_id, # 增加 region_id 'type': 'wx_pub', # 用户类型 'address': [], 'coupon': coupon, # 送优惠券 'app_id': '', # 微信先注册,没有app_id 'reg_time': app_helper.time_str(), 'wx_nickname': info.get('nickname', '游客'), 'wx_headimgurl': info.get('headimgurl', ''), 'wx_info': info, 'refresh_headimg': REFRESH_HEADIMG, 'last_status': int(time.time()), 'app_order_num': 0 # 20160927 lf 未下单 } # 用户中心注册用户接口 app_user_helper.new_user_info(openid, 'openid', new_set) is_our_fan = not (info.get('nickname', u'游客') == u'游客' ) # 是否是公众号粉丝,通过是否是游客判断 # 添加用户关系 2016-03-31 # 只有新注册用户添加 if parent not in [None, '']: from libs import user_tree parent_u = user_tree.owner2unionid(parent) if parent_u != None and unionid != parent_u: user_tree.add_parent(unionid, parent_u) print '======> TREE:', unionid, parent_u else: # 记录今天访问次数 last_date = db_user.get('last_visit_date') today_date = app_helper.time_str(format=1) # 格式 2016-01-01 if last_date != today_date: update_set = { 'last_visit_date': today_date, 'today_visit_count': 1, 'todat_visit_first_tick': int(time.time()), 'todat_push_image_text': 0, } else: update_set = { 'today_visit_count': db_user.get('today_visit_count', 0) + 1, } # 更新 region_id if db_user.get('region_id') != setting.region_id: update_set['region_id'] = setting.region_id if not openid_is_fun(openid) \ or db_user.get('wx_nickname', '')=='' \ or db_user.get('refresh_headimg',0)<=0: # 没有关注 # 用户基本信息 info = get_info(openid) if info.has_key('errcode'): get_ticket(True) info = get_info(openid) print info unionid = info.get('unionid', '') # 补充微信用户信息 update_set['unionid'] = unionid update_set['wx_nickname'] = info.get('nickname', '游客') update_set['wx_headimgurl'] = info.get('headimgurl', '') update_set['wx_info'] = info update_set['refresh_headimg'] = REFRESH_HEADIMG #db.app_user .update_one({'openid':openid}, {'$set': update_set}) app_user_helper.update_user_info(openid, q_type='openid', update_set=update_set) is_our_fan = not (info.get('nickname', u'游客') == u'游客') else: unionid = db_user.get('unionid', '') is_our_fan = True # 刷新refresh_headimg db.app_user.update_one({'openid': openid}, { '$set': update_set, '$inc': { 'refresh_headimg': -1 } }) uname = db_user.get('uname', '') # 生成 session ------------------ rand2 = app_helper.my_rand(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'openid': openid, 'unionid': unionid, 'ticket': ticket, 'uname': uname, 'login': 1, 'rand': rand2, 'ip': web.ctx.ip, 'attime': now, 'type': 'wx', 'auth_code': auth_code, # 20190516 记录来源 }) print "session >>>>>>>>>> ", session_id, openid, uname, auth_code if need_more_data: # 返回是否是粉丝 return session_id, is_our_fan, is_new_user, openid else: return session_id