def _aliyunoss(self): """阿里云存储""" if self.auth is None: access_key_id = self.alioss.get('access_key_id', '') access_key_secret = self.alioss.get('access_key_secret', '') endpoint = self.alioss.get('endpoint', '') self.bucket_name = self.alioss.get('bucket_name', '') self.auth = oss2.Auth(access_key_id, access_key_secret) bucket = oss2.Bucket(self.auth, endpoint, self.bucket_name) res = None try: res = bucket.put_object_from_file(self.key, self.target_filename, headers=self._headers()) except Exception as e: raise e if res.status / 100 != 2: log_error( '[AliyunOSSNetworkError] [FileUploadService] res.status:%d' % res.status) raise Exception(u'网络错误') return ('//%s/%s' % (self.alioss.get('cname', ''), self.key))
def deliver(): """确认收货""" if not check_login(): session['weixin_login_url'] = request.url return redirect(url_for('api.weixin.login')) uid = get_uid() args = request.args order_id = toint(args.get('order_id', 0)) if order_id <= 0: return '' ods = OrderDeliverService(order_id, uid) try: ods.deliver() except OrderException as e: msg = u'%s' % e.msg log_error(msg) return '' text, code = OrderStaticMethodsService.order_status_text_and_action_code( ods.order) return render_template('mobile/order/order.html.j2', order=ods.order, text=text, code=code)
def save_comment(): """评价订单商品""" resjson.action_code = 17 if not check_login(): return resjson.print_json(resjson.NOT_LOGIN) uid = get_uid() nickname = get_nickname() avatar = get_avatar() wtf_form = CommentOrderGoodsForm() current_time = current_timestamp() if not wtf_form.validate_on_submit(): for key, value in wtf_form.errors.items(): msg = value[0] return resjson.print_json(11, msg) og_id = wtf_form.og_id.data order_goods = OrderGoods.query.get(og_id) if not order_goods: return resjson.print_json(12, _(u'订单商品不存在')) order = Order.query.filter(Order.order_id == order_goods.order_id).filter( Order.uid == uid).first() if not order: return resjson.print_json(13, _(u'订单商品不存在')) data = {'uid': uid, 'nickname': nickname, 'avatar': avatar, 'ttype': 1, 'tid': order_goods.goods_id, 'rating': wtf_form.rating.data, 'content': wtf_form.content.data, 'img_data': wtf_form.img_data.data, 'add_time': current_time} comment = model_create(Comment, data, commit=True) item = Goods.query.get(order_goods.goods_id) if item: comment_count = Comment.query.\ filter(Comment.ttype == 1).\ filter(Comment.tid == order_goods.goods_id).count() good_count = Comment.query.\ filter(Comment.ttype == 1).\ filter(Comment.tid == order_goods.goods_id).\ filter(Comment.rating == 3).count() comment_good_rate = round( (Decimal(good_count)/Decimal(comment_count)) * 100) model_update(item, {'comment_count': comment_count, 'comment_good_rate': comment_good_rate}) model_update(order_goods, {'comment_id': comment.comment_id}, commit=True) # 站内消息 content = _(u'您已评价“%s”。' % order_goods.goods_name) mcs = MessageCreateService( 1, uid, -1, content, ttype=2, tid=og_id, current_time=current_time) if not mcs.check(): log_error('[ErrorViewApiOrderSaveComment][MessageCreateError] og_id:%s msg:%s' % ( og_id, mcs.msg)) else: mcs.do() return resjson.print_json(0, u'ok')
def cancel(): """取消订单""" if not check_login(): session['weixin_login_url'] = request.url return redirect(url_for('api.weixin.login')) uid = get_uid() args = request.args order_id = toint(args.get('order_id', 0)) cancel_desc = args.get('cancel_desc', '').strip() if order_id <= 0: return '' ocs = OrderCancelService(order_id, uid, cancel_desc) try: ocs.cancel() except OrderException as e: msg = u'%s' % e.msg log_error(msg) return '' text, code = OrderStaticMethodsService.order_status_text_and_action_code( ocs.order) return render_template('mobile/order/order.html.j2', order=ocs.order, text=text, code=code)
def deliver(self): """确认收货""" try: self.check() except OrderException as e: raise e data = { 'order_status': 2, 'deliver_status': 2, 'deliver_time': self.current_time} model_update(self.order, data) # 站内消息 content = _(u'您的订单%s已确认签收,请前往评价。' % self.order.order_sn) mcs = MessageCreateService( 1, self.order.uid, -1, content, ttype=1, tid=self.order.order_id, current_time=self.current_time) if not mcs.check(): log_error('order_id:%s msg:%s' % (self.order.order_id, mcs.msg)) else: mcs.do() db.session.commit() # 微信消息 WeixinMessageStaticMethodsService.deliver(self.order)
def cancel(self): """取消""" try: self.check() except OrderException as e: raise e data = { 'order_status': 3, 'cancel_status': self.cancel_status, 'cancel_desc': self.cancel_desc, 'cancel_time': self.current_time, 'update_time': self.current_time} model_update(self.order, data) # 站内消息 content = _(u'您的订单%s已取消。' % self.order.order_sn) mcs = MessageCreateService( 1, self.order.uid, -1, content, ttype=1, tid=self.order.order_id, current_time=self.current_time) if not mcs.check(): log_error('order_id:%s msg:%s' % (self.order.order_id, mcs.msg)) else: mcs.do() self.commit() return True
def push(self): """推送""" if not self.__check(): return False url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s' % self.access_token data = { 'touser': self.openid, 'template_id': self.template_id, 'data': self.data, 'url': self.url } data = json.dumps(data) response = requests.post(url, data=data) if response.status_code != 200: log_error( '[ErrorServiceWeixinWeiXinMpMessageServicePush][RequestError] request error.' ) return False data = response.json() errcode = data.get('errcode', 0) errmsg = data.get('errmsg', '') if errcode > 0: log_error('[ErrorServiceWeixinWeiXinMpMessageServicePush][RequestError] errcode:%s errmsg:%s' %\ (errcode, errmsg)) return False return True
def shipping(): """确认发货""" resjson.action_code = 10 form = request.form order_id = toint(form.get('order_id', 0)) shipping_sn = form.get('shipping_sn', '').strip() # operation_note = form.get('operation_note', '').strip() shipping_id = toint(form.get('shipping_id', 0)) current_time = current_timestamp() order = Order.query.get(order_id) if not order: return resjson.print_json(10, _(u'订单不存在')) if order.shipping_status == 2: return resjson.print_json(11, _(u'请勿重复发货')) if order.pay_status != 2: return resjson.print_json(12, _(u'未付款订单')) if shipping_sn == '': return resjson.print_json(13, _(u'请填写快递单号')) shipping = Shipping.query.get(shipping_id) if not shipping: return resjson.print_json(14, _(u'物流公司不存在')) order.shipping_id = shipping.shipping_id order.shipping_name = shipping.shipping_name order.shipping_code = shipping.shipping_code order.shipping_sn = shipping_sn order.shipping_status = 2 order.shipping_time = current_time order.deliver_status = 1 order.update_time = current_time # 站内消息 content = _(u'您的订单%s已发货,%s,快递单号%s,请注意查收。' % (order.order_sn, order.shipping_name, shipping_sn)) mcs = MessageCreateService(1, order.uid, -1, content, ttype=1, tid=order_id, current_time=current_time) if not mcs.check(): log_error( '[ErrorViewAdminOrderShipping][MessageCreateError] order_id:%s msg:%s' % (order_id, mcs.msg)) else: mcs.do() db.session.commit() # 微信消息 WeixinMessageStaticMethodsService.shipping(order) return resjson.print_json(0, u'ok')
def recharge_save(): """充值""" admin_uid = session.get('admin_uid', None) if not admin_uid: return_url = request.args.get('return_url', '/admin/dashboard') return redirect(url_for('admin.auth.login', return_url=return_url)) form = RechargeForm(request.form) form.avatar.data = request.args.get('avatar') if not form.validate_on_submit(): return render_template('admin/user/recharge.html.j2', form=form) recharge_amount = Decimal(form.recharge_amount.data).quantize( Decimal('0.00')) remark_user = _(u'充值成功') remark_sys = _(u'充值: 订单ID:%s, 充值方式:%s, 充值金额:%s' % (u"无", u"管理员打款", recharge_amount)) fs = FundsService(form.uid.data, recharge_amount, 1, 2, 0, remark_user, remark_sys, current_timestamp()) if not fs.check(): log_error( '[ErrorServiceApiOrderPaidServicePaid][FundsServiceError01] remark_sys:%s' % remark_sys) return redirect(url_for('admin.user.recharge', form=form)) # 更新余额 - 充值 fs.update() fs.commit() return redirect(url_for('admin.user.detail', uid=form.uid.data))
def _message(self): """站内消息""" content = _(u'您的订单%s已创建,请尽快完成支付。' % self.order.order_sn) mcs = MessageCreateService( 1, self.uid, -1, content, ttype=1, tid=self.order_id, current_time=self.current_time) if not mcs.check(): log_error('[MessageCreateError] order_id:%s msg:%s' % (self.order_id, mcs.msg)) else: mcs.do()
def __check(self): """检查""" utb = UserThirdBind.query.filter(UserThirdBind.uid == self.uid).first() if not utb or utb.third_user_id == '': log_error( '[ErrorServiceWeixinWeiXinMpMessageServiceCheck][UserError] no openid.' ) return False self.openid = utb.third_user_id wmats = WeiXinMpAccessTokenService() try: self.access_token = wmats.get_token() except Exception as e: log_error(u'[WeiXinMpMessageService] 获取token失败. %s' % e) return False if self.access_token == '': log_error( '[ErrorServiceWeixinWeiXinMpMessageServiceCheck][AccessTokenError] no token.' ) return False wmt = WeixinMpTemplate.query.get(self.wmt_id) if not wmt or wmt.template_id == '': log_error( '[ErrorServiceWeixinWeiXinMpMessageServiceCheck][TemplateError] no template.' ) return False self.template_id = wmt.template_id return True
def verify(self): """验证签名""" params = xml2json(self.xml)['xml'] _sign = params.get('sign', '') params.pop('sign') sign = self._create_sign(params) # 验证签名 if _sign != sign: log_error( '[ErrorServiceApiPayWeixinJsapiNotifyServiceVerify][VerifyError] xml:%s ' % self.xml) return False return True
def format_array_data_to_dict(datas=None, key_name=''): """ 转化元组数组为特定的字典数组(指定数据作为键名) """ new_datas = {} try: if not datas or not key_name: raise TheonestoreException(u'缺少数据') for day_data in datas: if key_name not in day_data.keys(): raise TheonestoreException(u'键名不存在') elif not isinstance(day_data, AbstractKeyedTuple): raise TheonestoreException(u'数据类型错误') else: dict_day_data = dict(zip(day_data.keys(), day_data)) new_datas[dict_day_data[key_name]] = dict_day_data except TheonestoreException as e: log_error(e.msg) finally: return new_datas
def __request_token(self): """获取token""" if not self.__check(): raise Exception(_(u'请先配置公众号')) params = { 'grant_type': 'client_credential', 'appid': self.appid.encode('utf8'), 'secret': self.secret.encode('utf8') } url = 'https://api.weixin.qq.com/cgi-bin/token' url = u'%s?%s' % (url, urlencode(params)) response = requests.get(url) if response.status_code != 200: log_error('[WeixinAccesstoken][RequestError] request error.') raise Exception(_(u'网络错误')) data = response.json() errcode = data.get('errcode', 0) errmsg = data.get('errmsg', '') if errcode > 0: log_error('[WeixinAccesstoken][RequestError] errcode:%s errmsg:%s' %\ (errcode, errmsg)) raise Exception(errmsg) token = data.get('access_token', '') expires_in = data.get('expires_in', 0) if not self.st: self.st = model_create(SysToken, { 'token_type': 'weixin_mp_token', 'add_time': self.current_time }) expires_in = self.current_time + expires_in - 60 model_update(self.st, { 'access_token': token, 'expires_in': expires_in }, commit=True) return token
def save(): """保存管理员""" primary_key = request.form.get('primary_key', '').strip() if primary_key and primary_key != '0': form = AdminUsersEditForm(CombinedMultiDict((request.files, request.form))) else: form = AdminUsersForm(CombinedMultiDict((request.files, request.form))) if not form.validate_on_submit(): return render_template('admin/auth/admin_user_detail.html.j2', form=form) admin_uid = toint(form.admin_uid.data) au = AdminUsers() if admin_uid > 0: au = AdminUsers.query.filter(AdminUsers.admin_uid == admin_uid).first() else: db.session.add(au) au.add_time = int(time.time()) au.salt = randomstr(random_len=32) password = sha256(form.password.data.encode('utf8')).hexdigest() sha256_password_salt = sha256((password+au.salt).encode('utf8')).hexdigest() au.password = sha256_password_salt avatar = '' if form.avatar.data: fus = FileUploadService() try: avatar = fus.save_storage(form.avatar.data, 'avatar') except Exception as e: log_error(u'[FileUploadService] Exception:%s' % e) form.avatar.errors = (_(u'上传失败,请检查云存储配置'),) return render_template('admin/auth/admin_user_detail.html.j2', form=form) au.username = form.username.data au.mobile = form.mobile.data au.nickname = form.username.data au.update_time = int(time.time()) au.avatar = avatar if avatar else au.avatar db.session.commit() return redirect(url_for('admin.auth.index'))
def __check(self): """检查""" ss = SysSetting.query.filter( SysSetting.key == 'config_weixin_mp').first() if not ss: log_error( '[WeiXinMpAccessTokenService][ConfigError] config is none.') return False try: config = json.loads(ss.value) except Exception as e: log_error( '[WeiXinMpAccessTokenService][ConfigError] config data error.' ) return False self.appid = config.get('appid', '') self.secret = config.get('secret', '') if (not self.appid) or (not self.secret): log_error( '[WeiXinMpAccessTokenService][ConfigError] config is empty.') return False return True
def save_storage(self, storage, category='default', filetype='image'): """保存文件 :param storage: 文件对象 :class:`~werkzeug.datastructures.FileStorage` object. :param category: 分类名称 :param filetype: 文件类型 """ files_dest = current_app.config['UPLOADED_FILES_DEST'] dirname = os.path.join(files_dest, category, self.today) # 创建目录 try: if not os.path.exists(dirname): os.makedirs(dirname) except OSError as e: log_error( u'[OSError] [FileUploadService.save_storage] exception:%s' % e) raise e # 保存文件到硬盘 filename_ext = extension(storage.filename).lower() uuid_hex = uuid.uuid4().hex filename = '%s.%s' % (uuid_hex, filename_ext) self.target_filename = os.path.join(dirname, filename) try: storage.save(self.target_filename) except Exception as e: raise e # 云oss存储的key self.key = '%s/%s/%s' % (category, self.today, filename) url = '' try: url = self._upload_oss() except Exception as e: log_debug(e) raise e return url
def create(self): """创建订单""" try: self.check() except TheonestoreException as e: log_error('[OrderService] [check] %s' % e) raise e # 订单id oi = OrderIndex() db.session.add(oi) db.session.commit() self.order_id = oi.order_id # 赋值 self._assign_order_goods() self._assign_order() self._assign_address() self._assign_shipping() self._assign_coupon() self._assign_payment() # 删除购物车 self._remove_cart() # 站内消息 self._message() # 订单之后的业务 self._commit_order_before() # 全部提交 db.session.commit() # 处理完订单之后的业务 self._commit_order_after() return self.order
def _qiniu(self): """七牛存储""" if self.auth is None: access_key = self.qiniu.get('access_key', '') secret_key = self.qiniu.get('secret_key', '') self.auth = qiniu.Auth(access_key, secret_key) self.bucket_name = self.qiniu.get('bucket_name', '') token = self.auth.upload_token(self.bucket_name) ret, info = None, None try: ret, info = qiniu.put_file(token, key=self.key, file_path=self.target_filename) except Exception as e: raise e if info.status_code != 200: log_error( '[QiniuNetworkError] [FileUploadService] info.status_code:%d' % info.status_code) raise Exception(u'网络错误') return ('//%s/%s' % (self.qiniu.get('cname', ''), self.key))
def __request_ticket(self): try: token = self.get_token() except Exception as e: log_error( _(u'[Error] [WeiXinMpAccessTokenService] [__request_ticket] 获取token失败. %s' % e)) raise e params = {'access_token': token, 'type': 'jsapi'} url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket' res = requests.get(url, params) if res.status_code != 200: log_error('[WeixinTicket][RequestError] request error.') raise Exception(_(u'网络错误')) data = res.json() errcode = data.get('errcode', 0) errmsg = data.get('errmsg', '') if errcode > 0: log_error('[WeixinTicket][RequestError] errcode:%s errmsg:%s' %\ (errcode, errmsg)) raise Exception(errmsg) ticket = data.get('ticket', '') expires_in = data.get('expires_in', 0) if not ticket or not expires_in: log_error( _(u'[Error] [WeiXinMpAccessTokenService] [__request_ticket] 获取ticket失败. ticket:%s, expires_in:%s' % (ticket, expires_in))) raise Exception(_(u'微信返回参数有误')) expires_in = self.current_time + expires_in - 60 st = SysToken() st.token_type = 'weixin_mp_ticket' st.access_token = ticket st.expires_in = expires_in st.add_time = self.current_time st.update_time = 0 db.session.add(st) db.session.commit() return ticket
def check(self): """检查""" repone_xml = ElementTree.fromstring(self.xml) return_code = repone_xml.getiterator('result_code')[0].text if return_code != 'SUCCESS': err_code = repone_xml.getiterator('err_code')[0].text err_code_des = repone_xml.getiterator('err_code_des')[0].text log_error('[ErrorServiceApiPayWeixinJsapiNotifyServiceVerify][ResponeError] xml:%s code:%s des:%s' %\ (self.xml, err_code, err_code_des)) return False cpw_ss = SysSetting.query.filter( SysSetting.key == 'config_paymethod_weixin').first() if not cpw_ss: log_error( '[ErrorServiceApiPayWeixinJsapiNotifyServiceVerify][SettingError01] xml:%s ' % self.xml) return False try: config_paymethod_weixin = json.loads(cpw_ss.value) except Exception as e: log_error( '[ErrorServiceApiPayWeixinJsapiNotifyServiceVerify][SettingError02] xml:%s ' % self.xml) return False self.partner_key = config_paymethod_weixin.get('partner_key', '') if self.partner_key == '': log_error( '[ErrorServiceApiPayWeixinJsapiNotifyServiceVerify][SettingError03] xml:%s ' % self.xml) return False self.transaction_id = repone_xml.getiterator('transaction_id')[0].text self.out_trade_no = toint( repone_xml.getiterator('out_trade_no')[0].text) self.total_fee = Decimal(repone_xml.getiterator('total_fee')[0].text) return True
def paid(self): """已付款业务处理""" pay_tran_id = self.kwargs.get('pay_tran_id', '') pay_method = self.kwargs.get('pay_method', '') paid_time = self.kwargs.get('paid_time', self.current_time) paid_amount = Decimal(self.kwargs.get('paid_amount', '0.00')) log_info('[PaidService] tran_id:%s paid_amount:%.2f' % ( self.tran_id, paid_amount)) # 检查 - 交易 tran = OrderTran.query.get(self.tran_id) if not tran: log_info( '[PaidService] not found tran: tran_id:%s' % self.tran_id) raise OrderException(_(u'找不到订单')) # 检查 - 订单 order_id_list = json.loads(tran.order_id_list) order_list = Order.query.filter( Order.order_id.in_(order_id_list)).all() if not order_list: log_info( '[PaidService] not found order list: tran_id:%s' % self.tran_id) raise OrderException(_(u'找不到订单')) # 检查 - 是否已经处理过 if tran.pay_status == 2: log_info('[PaidService] do already: tran_id:%s' % self.tran_id) return tran # 更新交易 model_update( tran, { 'pay_status': 2, 'pay_method': pay_method, 'paid_time': paid_time}) # 更新交易 - 支付流水号 if pay_tran_id: model_update(tran, {'pay_tran_id': pay_tran_id}) # 提交交易事务 db.session.commit() # 遍历更新订单及订单商品等 for order in order_list: order_id = order.order_id # 更新订单 data = { 'tran_id': self.tran_id, 'pay_method': tran.pay_method, 'pay_status': 2, 'pay_tran_id': tran.pay_tran_id, 'paid_time': paid_time, 'paid_amount': order.pay_amount, 'update_time': paid_time} # 普通订单 if order.order_type == 1: # 订单商品列表 og_list = OrderGoods.query.filter( OrderGoods.order_id == order_id).all() for og in og_list: goods = Goods.query.get(og.goods_id) if goods: # 销量 sale_count = goods.sale_count + og.goods_quantity # 库存 stock_quantity = goods.stock_quantity - og.goods_quantity # 更新商品 model_update( goods, { 'sale_count': sale_count, 'stock_quantity': stock_quantity}) # 更新订单 data['shipping_status'] = 1 # 充值订单 if order.order_type == 2: # 更新余额 - 充值 - 检查 remark_user = _(u'充值成功') remark_sys = _(u'充值: 订单ID:%s 支付方式:%s 第三方支付流水号:%s' % (order_id, tran.pay_method, tran.pay_tran_id)) fs = FundsService( order.uid, order.goods_amount, 1, 1, self.tran_id, remark_user, remark_sys, paid_time) if not fs.check(): log_error( '[FundsServiceError01] remark_sys:%s' % remark_sys) continue # 更新余额 - 充值 fs.update() model_update(order, data) # 站内消息 if order.order_type == 1: content = _(u'您的订单%s已支付,我们会尽快发货。' % order.order_sn) mcs = MessageCreateService( 1, order.uid, -1, content, ttype=1, tid=order_id, current_time=self.current_time) if not mcs.check(): log_error('order_id:%s msg:%s' % (order_id, mcs.msg)) else: mcs.do() # 提交订单事务 db.session.commit() # 微信消息 if order.order_type == 2: WeixinMessageStaticMethodsService.recharge(order) else: WeixinMessageStaticMethodsService.paid(order) return True